I need to read in values from the user, such as license plate, name, phone number, and service type.
I already got how to read it in if the user uses the return character after each input, ie:
A36 HTY
John Doe
(263)7742336
Bronze
But how can I read these values into my array if they're all on one line? I can read in word by word, but I need to be able to read in both halves of the license plate, and both the first and last name into one spot in the array.
I'd appreciate any help, thanks!
read the entire line and then use your software's programming to check whether there is any white space(s) in between the non-white spaces, and if there is, break the read string at the white space(s) into two different strings.
You can use isspace.
Use this link for assistance:
https://www.geeksforgeeks.org/isspace-in-c-and-its-application-to-count-whitespace-characters/
In this example, they use isspace for counting the number of whitespaces in a string. You can change the code to save each word in different string. Since I didn't write cpp for quite time now, I don't want to give you example that might be incorrect.
// input sentence
char buf[50] = "Geeks for Geeks";
ch = buf[0];
// counting spaces
while (ch != '\0') {
ch = buf[i];
if (isspace(ch))
count++;
i++;
}
// returning number of spaces
return (count);
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.
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.
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
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.
I'm trying to make my program read a file with 2 columns and the first column contains some strings and i cant make it to store into an array
Here is my code:
fp2=fopen("Symbol Table.txt","r");char str[100];
while(fscanf(fp2,"%s %s",str,stemp[scnt])!=NULL) {
puts(stemp[scnt++]);getch(); //This is just here to display conents of second col
}
fclose(fp2)
and here is my txt file:
void void
main Main
( Left Parenthesis
) Right Parenthesis
{ Left Brace
S Identifier
: Colon
$% Start of Block Comment
This program is a simple calculatorFuctions:ADD,SUB,MULT,DIV String
%$ End of Block Comment
Unsigned Noise Words
int Integer
the code store the long string is divided before going into the array
When you try to read strings with scanf or fscanf it reads the string until it encounters a space, a tab, or a newline. In this case, as I can see, in the first loop the str and stemp will be assigned to the stings "void" and "void", in the second loop, it will be "main" and "Main" and in the third loop, "(" and "Left" and so on.
You need to separate the two columns with multiple strings with a special character like the tab (\t) character so that one knows when the 1st column ends and read with the getc function instead of scanf until you reach that special character in your line and then combine all the characters (i.e. letters) in to a string. You can adopt the same method to read the second column with a getc function until you encounter the newline (\n).
while(fscanf(fp2,"%s %s",str,stemp[scnt])!=NULL) {
is not going to work
"%s" scans for non- white-space text. "This program is" and "Left Parenthesis" have embedded white-space.
Need to read a line-at-a-time and then parse the line into 2 strings for the 2 columns.
char buf[100];
if (fgets(buf, sizeof buf, fp2) == NULL) Handle_EOForIOError();
column[2][100];
size_t len = strlen(buf);
if (len < 62) Handle_ShortLine();
buf[61] = = '\0'; // cut the line in 2
column[0][0] = '\0'; // In case column is all white-space
sscanf(buf, " %[^\n]", column[0]);
column[1][0] = '\0';
sscanf(&buf[62], " %[^\n]", column[1]);
Other answers contain statements which are not true. Actually,
fscanf does not always read strings only until a white-space character. The conversion specifier [ also reads a string, and includes the set of expected characters.
You do not need to separate the two columns with a special character, since the columns are of known width 62.
You do not need to read a line at a time and then parse it; though, that might be easier.
So, if you prefer fscanf, you can use
while (fscanf(fp2, "%62[^\n]%[^\n]\n", str, stemp[scnt]) == 2)
(your comparing with NULL is wrong, because NULL is a pointer constant and fscanf doesn't return a pointer but the number of input items assigned or EOF).
A version without fscanf:
while (fgets(str, 62+1, fp2) && fgets(stemp[scnt], 62+1, fp2) && getc(fp2))
(The getc reads the \n.)
The Nature of while(fscanf(fp2,"%s %s",str,stemp[scnt])!=NULL) is will read only the two string separated by a space. if your text file contains long strings like this
This program is a simple calculatorFuctions:ADD,SUB,MULT,DIV
While fetching it will divide this strings into parts of %s %s and fetch. So change your text file in the following way and try:
void void
main Main
( LeftParenthesis
) RightParenthesis
{ LeftBrace
S Identifier
: Colon
$% StartofBlockComment
ThisProgramIsASimpleCalculatorFuctions:ADD,SUB,MULT,DIV String
%$ EndofBlockComment
Unsigned NoiseWords
int Integer
I am reading input from file (line by line) Each line is a state of a game board. Below is example of input:
(8,7,1,0,0,0,b,b,b,b,b,b,b,b,b,b,b,b,s,s,r,r,g,b,r,g,r,r,r,r,b,r,r,s,b,b,b,b,r,s,s,r,b,b,r,s,s,s,r,b,g,b,r,r,r,r,r,r,r,r,r,s) 0
I have used fgets() and strtok() to split the string at (),
My problem:
I want the first 6 integers in their individual variables such as:
int column = 8
int row = 7
so on..
I want to get rid of the last integer at the end of input- 0
and the chars should be stored in an array, because they represent pieces of a board.
Right now, I have an array with all the integers and chars stored together.
I can iterate through my array, and copy the integers to their variables and then chars to a new array. But that's inefficient.
Is there another way to do it?
I used fscanf() but don't know how to split the string using delimiters.
Thanks
WELL-FORMED INPUT ONLY
if (fscanf(FILE_PTR, "(%d,%d,...,%c,%c,%c,...,%c) %*d", &column, &row, ..., &chars[0], &chars[1], ...) == 60)
or something like that
the %*d specifier will discard that input (you didn't want the last number)
for the chars, give pointers to their indices for a preallocated array
for the ints, give the variable pointer/ref
Thank you to Jon Leffler for reminding that you should test the output of *scanf (number of things read)!
More information
REEDIT nope, it was right -
int fscanf ( FILE * stream, const char * format, ... );
format: C string that contains a sequence of characters that control how characters extracted from the stream are treated:
Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters -- see isspace). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).
Non-whitespace character, except format specifier (%): Any character that is not either a whitespace character (blank, newline or tab) or part of a format specifier (which begin with a % character) causes the function to read the next character from the stream, compare it to this non-whitespace character and if it matches, it is discarded and the function continues with the next character of format. If the character does not match, the function fails, returning and leaving subsequent characters of the stream unread.
Format specifiers: A sequence formed by an initial percentage sign (%) indicates a format specifier, which is used to specify the type and format of the data to be retrieved from the stream and stored into the locations pointed by the additional arguments.
Above quote from here. I am aware of the hostility towards cplusplus.com here but I do not have access to the standard. please feel free to edit if you do
I have used fgets() and strtok() to split the string at "()"
later
I used fscanf() but don't know how to split the string using delimiters.
I guess if strtok() worked for parenthesis, it would work for commas too.
Apart from that: you have several possibilities for doing what you want. Without much context provided, I can't really tell you which one you want, but here we go:
Grab a pointer to the first non-integer, and use it as if it was a pointer to the first element of another array, containing the integers only. This avoids all copying and/or moving overhead.
Use memcpy() to copy only the necessary parts of the array to another array. memcpy() is generally highly optimized and faster than the naive for-loop-with-assignment approach.
if you have a char * you can think of it as an array or as a string, as the memory layout is the same...
char * input = "(8,7,1,0,0,0,b,b,b,b,b,b,b,b,b,b,b,b,s,s,r,r,g,b,r,g,r,r,r,r,b,r,r,s,b,b,b,b,r,s,s,r,b,b,r,s,s,s,r,b,g,b,r,r,r,r,r,r,r,r,r,s) 0";
size_t len = strlen(input);
int currentIndex = 0;
char * output = calloc(1,len);
for (int i = 0 ; i<len ; i++)
{
if (input[i] == '(' || input[i] == ')' || input[i] == ','|| input[i] == ' ') {
continue;
}
output[currentIndex++] = input[i];
}
assert(strlen(output) == 63); //well formatted?
char a = output[0];
char b = output[1];
char (* board)[60] = malloc(60); //pointer to array or is it a mal-formed string.
memcpy(board, output+2, 60);
char last = output[62];
the main thing that I would add, if you want to use it more like a string, then you have to make the array 1 bigger and set board[60] = \0;
I have been struggling to figure out the fscanf formatting. I just want to read in a file of words delimited by spaces. And I want to discard any strings that contain non-alphabetic characters.
char temp_text[100];
while(fscanf(fcorpus, "%101[a-zA-Z]s", temp_text) == 1) {
printf("%s\n", temp_text);
}
I've tried the above code both with and without the 's'. I read in another stackoverflow thread that the s when used like that will be interpreted as a literal 's' and not as a string. Either way - when I include the s and when I do not include the s - I can only get the first word from the file I am reading through to print out.
The %[ scan specifier does not skip leading spaces. Either add a space before it or at the end in place of your s. Also you have your 100 and 101 backwards and thus a serious buffer overflow bug.
The s isn't needed.
Here are a few things to try:
Print out the return value from fscanf, and make sure it is 1.
Make sure that the fscanf is consuming the whitespace by using fgetc to get the next character and printing it out.