This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed last month.
The community is reviewing whether to reopen this question as of 22 days ago.
I'm trying to read a file from txt docs and display the data, but when I run the code, it displays nothing and just shows like this:
enter image description here
I'm not sure where the problem is with my code, but perhaps the problem is because I need to display 4000 columns of data so the program cannot read and display it. I tried to use another sample txt with 10 columns of data and the code worked but not with 4000 columns of data.
This is my code :
char str [101][101];
FILE *fin = fopen ("test.txt", "r");
int count = 0;
while (!feof(fin)){
fscanf (fin, "%s", str[count]);
count++;
}
fclose(fin);
for (int i = 0 ; i < count ; i++){
printf("%s\n", str[i]);
}
This is data I want to read and display (4000 columns data)
Bali
Paris
Japan
Nepal
India
Rusia
Malaysia
Thailand
England
etc....
Thank you in advance!!
I haven't tried to run the code.
You read a file line by line and put every line within str. However, str can only contain a maximum of 101 lines, with each iteration not exceeding 100 chars.
Increase the value of str to at least 4000.
str[4500][101]
EDIT:
The question has been flagged as duplicate; however, the problem here is linked to how the C language works.
In this example, we have a static two-dimensional array for which C reserved some memory on the stack. As C tries to use more memory than allocated, the O.S. will inform the process that it does not have access to the location. Which makes C raise an exception at runtime.
I think bringing this precision to those who learn C is essential to avoid confusion.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am expected to make a program to calculate and display statistics about the length of words in a text file. I have been provided the following file
int readFile(const char fName[], char textStr[]){
FILE *fPtr;
char ch;
int size = 0;
if ((fPtr = fopen(fName, "r")) == NULL) {
fprintf(stderr, "Error, failed to open %s: ", fName);
perror("");
return 1;
}
while ((ch = fgetc(fPtr)) != EOF) {
if (size >= MAX_FILE - 1)
break;
textStr[size++] = ch;
}
textStr[size] = '\0';
return size;
}
I was able to verify that I can access the file using the following code
int main() {
char str[MAX_FILE];
int len = readFile("test.txt", str);
if (len == -1) {
printf("An error occurred\n");
} else {
printf("file read");
}
}
File test.txt contains
The quick brown fox jumps over the lazy dog
What I want to do is to get the contents of test.txt and find the length of each word in it something like:-
1 letter words- 0
2 letter words - 0
3 letter words - 3
4 letter words -4
and so on...
As a fellow new contributor, I'm going to give you a break and try to answer the question you didn't ask. ;)
I believe the question is "how to proceed". This is going to be a long answer as I will try be very detailed since you seem to be a newbie. Hopefully this will help you or maybe someone else.
The trick is to take a word problem and convert it into a mathematical solution. The best way to do this is to write "pseudocode". (See Wikipedia for more information, if you need to.) I'm going to give you some pseudocode at the end, but since this appears to be a homework assignment, please try to write your own pseudocode first. If you read the pseudocode and it still doesn't help, I can post my solution later. (I'm not a great programmer so it might not be the best program. And it took way overlong to come up with it.)
First things first: There appears to be a typo in the code you posted. In the source code you were provided, the problem is the return 1 statement if the file isn't found. That should be return -1, because what would happen if you had a test file that had exactly 1 letter? The code wouldn't work correctly.
Now, to first convert the word problem you were given: You need to have an array of word counts to keep track of 1-letter, 2-letter, etc. words. Now according to this the longest word in the English dictionary is 45 letters. So, in theory, you would need to have an array of 45 elements of wordCounts. You can shorten this as required.
Now to process your str variable, you need a while statement to go through one character at a time. Since the characters in the string go from element 0 through one less that the len variable, you need to code the while accordingly.
Within that while, you need another while. This while needs to count up the wordLength one character at a time, until you see a blank or the trailing '/0' character of str. To do this, you initialize the wordLength to zero right before the second while. Then add 1 to the wordLength for each character you count and increment your subscript.
At the end of this inner while you need to accumulate your wordCounts. Keep in mind that your 1-letter words are going to be accumulated into element 0 of your array. So you need to adjust the wordLength - 1 array element. After that you need to increment your subscript you are using to go through your str, one character at a time.
At the end, you need to print out the wordCounts array values. Since most of the word lengths will have a value of zero, I wouldn't print these. Unless you set the maximum length of the wordCounts array to something like 10, instead of 45. You want a for loop to go through your wordCounts array, and do something like this: printf("%2d letter words = %d", ..., ...);. Keep in mind your 1-letter words are going to be in element 0;
That is a very detailed version of a word problem that is the solution to the problem of "count the number of words that the phrase has from 1-letter words to x-letter words".
Here is the pseudocode I came up with, after coding my solution. It is a little more detailed than normal pseudocode would be. (Personally, I abbreviate all variable names and use Pascal case, but that's just me.)
Declare a numeric array of wordCounts and a subscript.
For each element of wordCounts, zero out the number of words or the code won't work right.
Reinitialize subscript to zero.
As long as (while) the subscript is less than the len, continue.
Initialize the wordLength to zero.
As long as the str[subscript] is not a blank or a null character, add 1 to the wordLength.
Increment the subscript.
After both while statements are complete print out the array of wordLengths, as described above.
Your done!
Now I could post the actual code that could be used to come up with this pseudocode, but it would be better if you came up with it yourself. If you try but have a bug in your code, post a new question, and I'll try to check back to answer it. Hope this helps you or someone else.
This question already has answers here:
C Programming - Read specific line from text file
(2 answers)
Closed 5 years ago.
Assume I have a binary file data.bin of 1000 lines that was written using fwrite. For reading it, I just have to do something like this(where data is a double buffer of size 1000):
FILE *fp = fopen("data.bin", "rb");
fread(data, sizeof(double), (1000*sizeof(double),fp);
This will read the entire file but I am looking for reading only the last 500 lines!! This means I have to jump to the line 499 in data.bin and start reading from there until the end. How to do modify the previous fread function to read the last 500 lines?
Thank you.
Are you aware of the fseek() function. You need to set the pointer to begin at the last 500 lines then read until eof.
Look up fseek() and you will be able to solve this problem.
Here is a link for further information on fseek()
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I've created a struct with 2 char[] and one int. I created an array of this struct and scanfed several inputs to store data into the array. Then I used fprintf to write this data to the file. But when I open the file I get û before every new record. Idk why is it happening.
Here's the relevant code:
FILE *outputFile=fopen("1021.txt","ab");
int tickets=0,i=1;
struct air s[30];
printf("\nEnter Number of tickets:");
scanf("%d",&tickets);
for (i=1;i<=tickets;i++)
{
printf("\nEnter the name\t");
scanf("%s",&s[i].name);
printf("\nEnter the phone number\t");
scanf("%s",&s[i].phoneNo);
printf("\n Enter the address\t");
scanf("%s",&s[i].address);
printf("Your ticket is confirmed\t");
getch();
}
for (i=0;i<=tickets;i++)
{
printf("%s", s[i].name);
printf("%s", s[i].phoneNo);
printf("%s", s[i].address);
fprintf(outputFile,"%s",s[i].name);
fprintf(outputFile,"%s",s[i].phoneNo);
fprintf(outputFile,"%s",s[i].address);
}
Here's what I get in the file:
ûdalla03332228458dallaÈfsÇûÿÿÿÿàrancho03312041265dallabancho
Where are those unusual characters coming from?
Your input loop is
for (i=1;i<=tickets;i++)
but the output loop is
for (i=0;i<=tickets;i++)
So you are writing data to file from element [0] that you have no data entered for. That is why it is junk.
In C, arrays are indexed from [0], and neither of those loops is right. Please change both of them to
for (i = 0; i < tickets; i++)
There are other problems in the code too, but this addresses the immediate "uninitialised data" problem.
Edit: some other problems.
You opened the file in "binary" mode, but you are using it as a text file. I believe the distinction is only necessary in Windows.
FILE *outputFile=fopen("1021.txt", "at"); // change to "t"
The string address passed to scanf should not contain an & address-of (unlike an int). Just pass the array - it decays to the required pointer.
scanf("%s", s[i].name); // removed `&`
As you have not written any newline to file to demark your string data, when you read the data back in, you will not know where each ends and the next begins. So for example, add the newline like this
fprintf(outputFile, "%s\n", s[i].name); // added \n
You say one member is an int presumably the phone number, but you are inputting as a string. Yet it is a bad idea to store phone numbers as integers, because a) thay might contain a character such as '+' or b) may start with a leading 0 and that will be lost when you store as int. So change the struct member phoneNo to be a char array of adequate length.
The scanf format specifier %s will stop at the first whitespace it meets, so the input statements will be better as this, which will only stop when it finds a newline or hits the length limit:
int res = scanf("%29[^\n]", s[i].name);
where the array length defined was [30] (you did not show the struct). Alternatively you could research the use of fgets().
Finally, you should check the return value of the functions you are calling to see if they were successful. fopen will tell you if the file opened correctly. scanf will tell you the number of entries it scanned, and fgets tells you if it was successful too.
This question already has answers here:
Reading a C file, read an extra line, why?
(6 answers)
Closed 8 years ago.
I am trying to write a C program that is able to read data (strings) from a text file and swap each content in terms of bytes. I have already implemented the code and everything works just fine, and and I am able to read all the contents of the specified text file, but the problem is that the program is printing the last word from the text file twice and I do not know why? Any help will be helpful ! This is the code I have:
while( !feof(ptr_file))
{
//to read in group of words (sentences) if
//needed !.
fscanf(ptr_file, "%s", userName);
//time to swap letters of the word coming from the text file.
swap_a_word(userName, 0, 4);
swap_a_word(userName, 1, 2);
//new space.
printf("\n");
//display the word after swapping to the screen for the user.
printf("%s", userName);
}
The program must not print extra data. I do not know, but when the program reaches the end of the file, it prints the last data of the text file twice. Please any hints will be helpful !.
Thanks !
The problem is the while loop condition
while(!feof(ptr_file))
Note that EOF is preceded by a newline '\n'. fscanf returns the value EOF when the end of file is reached. However, this does not set the end-of-file indicator on the stream and as a result the loop is entered one extra time. You should check the return value of fscanf instead to find number of items successfully matched and assigned.
Say I'm calling a program:
$ ./dataset < filename
where filename is any file with x amount of line pairs where the first line contains a string and second line contains 10 numbers separated by spaces. The last line ends with "END"
How can I then start putting the first lines of pairs (string) into:
char *experiments[20] // max of 20 pairs
and the second lines of the pairs (numbers) into:
int data[10][20] // max of 20, 10 integers each
Any guidance? I don't even understand how I'm supposed to scan the file into my arrays.
Update:
So say this is my file:
Test One
0 1 2 3 4 5 6 7 8 9
END
Then redirecting this file would mean if I want to put the first line into my *experiments, that I would need to scan it as such?
scanf("%s", *experiments[0]);
Doing so gives me an error: Segmentation fault (core dumped)
What is incorrect about this?
Say my file is simply numbers, for ex:
0 1 2 3 4 5 6 7 8 9
Then,
scanf("%d", data[0][0]); works, and will hold value of '1'. Is there an easier way to do this for the whole line of data? i.e. data[0-9][0].
find the pseudo-code, code explains how to read the input
int main()
{
char str[100]; // make sure that this size is enough to hold the single line
int no_line=1;
while(gets(str) != NULL && strcmp(str,"END"))
{
if(no_line % 2 == 0)
{
/*read integer values from the string "str" using sscanf, sscanf can be called in a loop with %d untill it fails */
}
else
{
/*strore string in your variable "experiments" , before copying allocate a memory for the each entry */
}
no_line++;
}
}
The redirected file is associated with the FILE * stdin. It's already opened for you...
otherwise, you can treat it the same as any other text file, and/or use the functions that are dedicated to standard input - with the only exception that you cannot seek in the file and not retrieve the size of the input.
For the data sizes you're talking about, by far the easiest thing to do is just slurp all of the content into a buffer and work on that: you don't have to be super-stingy, just make sure that you don't overrun.
If you want to be super-stingy with memory, preallocate a 4kB buffer with malloc(), progressively read() into it from stdin, and realloc() another 4kB every time the input exceeds what you've already read. If you don't care so much about being stingy with memory (e.g. on a modern machine with gigabytes of memory), just malloc() something much bigger than the expected input (e.g. a megabyte) and bug out if the input is more than that: this is far simpler to implement but less general/elegant.
You then have all of the input in a buffer and you can do what you like with it, which depends too strongly on the format of the input for me to say how you should approach that part.