An issue with my code has risen up in the matter of scanning in characters from a file. Here is my code:
int main(int argc, char **argv){
FILE *ifp = fopen("input.txt", "r");
char check, key;
char buffer[MAX_STRING_LENGTH + 1];
char str[MAX_STRING_LENGTH + 1];
node *head = NULL;
fscanf(ifp, "%s", buffer);
head = stringToList(buffer);
while(fscanf(ifp, "%c", &check) != EOF){
switch(check){
case '#':
//fflush(stdin); //this is commented out because fflush
fscanf(ifp, "%c", &key); //did not seem to solve the issue
fscanf(ifp, "%s", str);
printf("%c, %s\n", key, str);
head = replaceChar(head, key, str);
break;
//more cases follow, but they are irrelevant to this question
My issue here is that my program is failing to scan in a character to key when called. When the input for the particular case from the file says, for example,
# r ri
The print statement gives the following:
( ), (r)
There is a blank space in the print statement which should print r, and as far as I can tell the character is instead scanning into the string. Thus the program is dysfunctional. I need to know how to properly scan in this character. Thank you.
fscanf(ifp, " %c", &key); then fscanf(ifp, " %s", str); notice the additional spaces. You are reading a ' ' after reading the '#'. – David C. Rankin
This has answered my question. Pretty strange that C would be messed up by something so simple.
Related
I'm trying to make a program in C for reading in lines of text from a file, and creating nodes to build a tree. these nodes are structs. To do this, I'm trying to read six lines at a time. whenever my program gets to the fscanf line however, it doesn't seem to read anything, setting my int to EOF and exiting the function. I've tried a great deal of format combinations, removing and adding spaces, \n and the like. I've even tried making a separate fscanf line to attempt to read in a single string, and even that seems to scan nothing. I have no idea why this is happening. here's the relevant code:
member_ptr readAndCreate(FILE * file){
member_node * temp;
temp = calloc(1, sizeof(member_node));
//char temp_char_array[50] = {0,0,0,0,0};
//char *overflow;
int isEnd;
//isEnd = fscanf(file, " %s", temp_char_array);
//isEnd =
isEnd = fscanf(file, " %[^\n] %[^\n] %d %[^\n] %[^\n] %[^\n]",
temp -> family,
temp -> personal,
&temp ->ID,
temp -> email,
temp -> boatClass,
temp -> boatName
);
//temp->ID = (int)strtol(temp_char_array, &overflow, 10);
if (isEnd == EOF){
printf("Something went wrong, please try again \n");
return NULL;
} else {
return temp;
}
}
and this is the main function
int main() {
char pathname[100];
FILE * file;
member_ptr top;
member_ptr temp;
printf("input file path\n");
scanf("%[^\n]", pathname);
file = fopen(pathname, "r");
if (file == NULL){
printf("file cannot be found, closing program...");
exit(1);
}
top = readAndCreate(file);
genTree(top, file);
printOutTree(top);
printf("Hello, World!\n");
return 0;
}
I see a problem with your scan codes. The s designating string input seems to be missing.
Try changing
isEnd = fscanf(file, " %[^\n] %[^\n] %d %[^\n] %[^\n] %[^\n]",
into
isEnd = fscanf(file, " %[^\n]s %[^\n]s %d %[^\n]s %[^\n]s %[^\n]s",
You have the same bug in the main() function.
My assignment is to write a function that takes an input string from a user, tokenize it into several strings each containing an individual word from the input sentence, and then reverses the sentence. The result will be the sentence input but with the words in the reverse order.
For now, I just have the function taking in the input, tokenizing it into individual words, storing those words into an array, and printing out each individual word in order. I do not have the process for reversing the order of the words written yet.
Here is the code for the function i have handling this so far:
void reverse(void){
printf("\n\n%s\n", "Reverse words in String: ");
char input[200];
printf("\n%s", "Enter string\n> ");
scanf("%s", &input);
char reverseSentence[200];
char sentenceParts[20][200];
int wordCount = 0;
char *thisWord = strtok(input, " ");
strcpy(sentenceParts[wordCount], thisWord);
wordCount++;
while(thisWord != NULL){
thisWord = strtok(NULL, " ");
strcpy(sentenceParts[wordCount], thisWord);
wordCount++;
}
printf("\n\n");
for(int i = 0; i < wordCount + 1; ++i){
printf("%s%s", sentenceParts[i], " ");
}
}
The problem lies in the while statement:
while(thisWord != NULL){
thisWord = strtok(NULL, " ");
strcpy(sentenceParts[wordCount], thisWord);
wordCount++;
}
The program exits with a segmentation fault error at the strcpy statement. I cannot understand for the life of me why it is doing this. It seems like it worked just fine outside of the while loop.
Any thoughts? I've been stuck on this for quite a bit now and can't find too many other resources out there to help.
Updating thisWord with the next token should happen at the end of the loop body. As is, you'll eventually update thisWord with a NULL, and then call strcpy with a NULL. And that is your segfault.
So the loop should look like this:
char *thisWord = strtok(input, " ");
while(thisWord != NULL){
strcpy(sentenceParts[wordCount], thisWord);
wordCount++;
thisWord = strtok(NULL, " ");
}
The other problem (pointed out by #WhozCraig in the comments) is that you are inputting the line using scanf("%s", ...). That doesn't work because scanf will stop at the first whitespace character. Hence, you'll only get one word at a time from scanf. To get an entire line, use the fgets function.
I am working on a practice problem from my textbook by kernigan and ritchie (again for practice, not for credit).
The problem states to write a program that prints a histogram of the lengths of words in its input.
I want to do this by printing a "_" for every char that I read. However, I'm having a lot of trouble reading chars.
Right now, my program looks like this:
int main(){
int c;
char str[100];
scanf("%s", str);
printf("|");
while((c = getchar()) != EOF){
putchar(c);
printf("_");
}
printf("|");
return 0;
}
main compiles. However When I try to use it and give it a word (of any length), it simply prints:
|
_
and then the cursor moves right next to the underscore. What am I doing wrong? Why is the underscore printed after the "|" rather than next to it, as I didn't use \n ?
The output you see is because the scanf("%s", str) line captures the word you input up to the default delimiter character which is space and then goes on to print '|' character then attempts to read more from stdin.
If you had entered say mylong word do you like it? then ctrl-z
You would see:
| _w_o_r_d_ _d_o_ _y_o_u_ _l_i_k_e_ _i_t_?_
_^Z
|
This is because the characters word do you like it? are still in the stream to be processed.
If you only enter a single word without spaces then you will see what you observed.
The two lines:
char str[100];
scanf("%s", str);
could be removed and then you won't be capturing the word and doing nothing with it.
Alternatively, if you want to use scanf you could change like this:
#include <stdio.h>
int main(){
char str[100];
char* p = str;
scanf("%s", str);
printf("|");
while (*p != NULL) {
putchar(*p++);
printf("_");
}
printf("|");
return 0;
}
This code prints each character in str, interspersing with the _ character.
**I'm still fairly new to C and this is a beginner question. I am trying to read a line of integers separated by a whitespace from a file that I have already written to, but it is not working. When I try to print the integers to screen, I get -1. I'm not sure why this is happening:
#include <stdio.h>
int main() {
//create an array of characters
char str1[10];
//ask the user to enter a file name
printf("Enter a file name\n");
//str1 holds the address of the file name user enters
scanf("%s", str1);
FILE *fp;
fp = fopen(str1, "w+");
//write integer values to created file, separated by a space
fprintf(fp, "%d", 2);
fprintf(fp,"%c", ' ');
fprintf(fp, "%d", 4);
fprintf(fp,"%c", ' ');
fprintf(fp, "%d", 5);
fprintf(fp, "%c", ' ');
fprintf(fp, "%d", 7);
fprintf(fp, "%c", ' ');
fprintf(fp,"%d", 9);
int number;
int counter, c=0;
//if nothing is in file, then print error statement
if (fp==NULL){
printf("File cannot be read");
}
c = fscanf(fp, "%d", &number);
while (c !=EOF){
counter++;
c = fscanf(fp, "%d", &number);
printf("%d",c);
}
fclose(fp);
}
How do I properly print the integers to screen? (count is being used later to calculate the average, and I am originally asking the user to enter a file name that will have integers written to a file)
You have a number of problems:
After writing to the file the position is at the end of the file. Need to rewind to start back at the beginning of the file before reading it.
The printf should print number not c.
The printf should be placed before the fscanf in the loop. Otherwise the first number is missed and the last print is for the fscanf that has returned EOF (ie, number not valid for that last case).
Sorry for a stupid question, but this is really starting to annoy me.
I need to take a line of input from a console. Here's the relavent fragment of code:
int number_read=0;
char line[80];
printf("Enter register address: ");
number_read = scanf("%s\n", line);
printf("number of characters entered: %d; characters entered: %s.\n", number_read, line);
if (number_read > 0) {
<read some registers and display the results.>
}
It doesn't work. The "Enter register address" line is printed, and the cursor stops at the end of the line, and moves to the next line when I press enter, but then nothing else happens. I've tried replacing scanf() with fscanf(stdin,...), with fgets(stdin), gets, GNU's getline(), a short function that does the same thing, with diagnostics:
char *new_line, ch;
for(;;) {
ch = fgetc(stdin);
if(ch == EOF) break;
if((*line++ = ch) == '\n') break;
printf("Line so far: %s\n", line);
}
*line='\0';
I get the same response from all of them. I'm including all the requisite headers.
I'm on a Windows XP box, compiling with gcc 3.4.5 (mingw).
Can anyone see what I'm doing wrong?
In scanf you should use a %i to represent a int so, try with
scanf("%I", number_line);
The following code will works,
char buff_msg[1024];
while(1)
{
if(fgets(buff_msg,1024, stdin) != NULL){
printf("%s\n", buff_msg);
memset(buff_msg, 0, 1024); // you will need this line
}
}
You can
break the loop on your own condition
try read() it works in MinGW replace
this
number_read = scanf("%s\n", line);
with this also include #include<unistd.h>
number_read = read(STDIN_FILENO, (void *)line,sizeof line);
value scanf returns is not the number of strings in the number of elements to read(this case meybe 1).
Use the %n To get the number, such as desired.
scanf("%s%n", line, &number_read);
printf("number of characters entered: %d; characters entered: %s.\n", number_read, line);