2

I am attempting to read a line written in the format:

someword:    .asciiz     "want this as a char*"

There is an arbitrary amount of white space between words. I am curious if there is a simple way of getting the internal characters in the quotes into a char* variable using something like sscanf? I am guaranteed the quotes and that where will be no more than 32 characters (including spaces). There will also be a new line character immediately following the quotes.

  • http://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf - looks like `scanf("%10[0-9a-zA-Z ]", str);` is the easiest solution - or this: `scanf("%20[^\n]", name);`. – omerfarukdogan Apr 27 '15 at 20:11

3 Answers3

1

Most scanf() field descriptors implicitly cause leading whitespace to be skipped and expect the field to be whitespace-terminated. To scan a string that may contain whitespace, however, you can use the %[] field descriptor with an appropriate scan set. Thus, you might scan sequence of lines following the pattern you describe like so by looping calls like this:

char keyword[32], value[32], description[32];
scanf("%s%s%*[ \t]\"%[^\"]\"", keyword, value, description);

That format string:

  • scans two whitespace-delimited strings into char arrays keyword and value,
  • scans but does not assign one or more whitespace characters followed by a quotation mark,
  • scans everything up to but not including the next quotation mark into char array description, and scans and discards a quotation mark.

It relies on the data to be correctly formatted; among other things, this is vulnerable to a buffer overflow if the data are malformed. You can address that by specifying maximum field widths in the format string.

Note, too, that you should check the return value of the function to ensure that all fields were successfully matched. That will allow you to terminate early in the event of malformed input, and even to present valid information about the location of the malformation.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Note: "return value of the function to ensure that all fields were successfully matched" mostly works here but misses some things. The expected return value of 3 is the count of _format specifiers_ matched and would only detect up to `"%[^\"]"`. Matching or not of the final directive `\"` is not reported. – chux - Reinstate Monica Apr 27 '15 at 23:09
  • works perfectly, the explanations will allow me to apply this to other problems. Thank you very much. –  Apr 28 '15 at 18:10
0

You can use scanf ("%s%s%31[^\n]",s1,s2,s3);

Example:

#include <stdio.h>

int main()
{
    char s1[32],s2[32],s3[32];
    printf ("write something: ");
    scanf ("%s%s%31[^\n]",s1,s2,s3);
    printf ("%s %s %s",s1,s2,s3);
    return 0;
}

s1 and s2 will ignore spaces but s3 won't

Jahid
  • 21,542
  • 10
  • 90
  • 108
0

Use \"%32[^\"]\" to capture the quoted phrase. Use "%n" to detect success.

char w1[32+1];
char w2[32+1];
char w3[32+1];
int n = 0;
sscanf(buffer, "%32s%32s \"%32[^\"]\" %n", w1, w2, w3, &n);
if (n == 0) return fail;    // format mis-match
if (buffer[n]) return fail; // Extra garbage detected
// else good to go.

"%32s" Skip white-space,then read & save up to 32 non-white-space char. Append '\0'.
" " Skip white space.
"\"" Match a '\"'.
"%32[^\"]" Read and save up to 32 non-'\"' char. Append '\0'.
"%n" Save the count of characters scanned.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256