I would like to read all numbers from .txt file using sscanf. In the main function, I opened the .txt file with fopen( name.txt, "r").
The following code is only reading first strings and first numbers, but I can't iterate it:
int test(FILE *file){
int l = 0;
char buffer[256];
char *poi = NULL;
while(fgets(buffer, 256, file) != NULL){
poi = buffer;
for(;*poi != '\n'; poi++){
sscanf(buffer, "%[^0-9]%d", zahl[l].buf, &zahl[l].number);
l++;
}
}
For instance:
In the .txt file is following text:
In 2019 we had 200 accidents
In 2020 we had 199 accidents
The code above would only read 2019 and 2020, but not 200 or 199 - how can I tell sscanf to keep scanning until new line '\n' appears?
A couple of things:
You're always scanning from the start of buffer, you need to scan from poi (point of interest?)
You need to advance poi by the number of characters read
A newline character might not be present in buffer
For the second point you can use %n to get the number of characters read so far.
With this you end with a loop like:
while (*poi) {
int nc;
if (2 == sscanf(poi, "%[^0-9]%d%n", zahl[l].buf, &zahl[l].number, &nc))
poi += nc;
else
break;
l++;
}
Related
I would like to copy a huge txt file and 'shrink' it. this is my code, but it seems it's still takes a lot of time reading the file. is there a way to read from a specific line number to EOF? for instance, the first 1 million lines are not useful to me, how to read from line 1 million. or anyway to read from EOF?
include<stdio.h>
include<stdlib.h>
void main() {
FILE *fp1, *fp2;
char ch;
int i = 1;
int n = 0;
int k;
fp1 = fopen("co.data", "r"); /* open a file to read*/
fp2 = fopen("Output.txt", "w"); /* open a file to write*/
printf("please enter how many lines do not need to be copied\n");
scanf ("%d", &k);
while (1) {
ch = fgetc(fp1); /* a loop to read/copy the file*/
if (ch == '\n') /* record the number of lines*/
i++;
if (ch == EOF)
break;
else if (i>k)
putc(ch, fp2);
}
printf("File copied Successfully!\n");
printf("number of lines read is %d\n",i-1);
printf("number of lines copied is %d\n",i-1-k);
fclose(fp1);
fclose(fp2);
}
There are two potential answers to your question, depending on if your file has known line lengths or not.
is there a way to read from a specific line number to EOF
In a file with line lengths are completely arbitrary (variable), no.
For example, if line 1 is 10 characters, and line 2 is 20 characters, then there is no way to calculate where line 3 is going to start without iterating through lines 1 and 2.
Operating systems aren't magic; if this kind of functionality was supported, they'd have to iterate through the file first as well. Either way, you're going to be looping through the contents.
Now, if the line lengths are guaranteed to be the same, that's a different story.
Say you have a text file like so:
AAAAAAA
BBBBBBB
CCCCCCC
Each line in the above text file is 7 characters. Assuming your line terminator is \n, each line takes up exactly 8 bytes.
In this case, you can safely fread() 8 bytes at a time and know that you're getting exactly one line. In order to jump to a particular byte in a file, you would use fseek().
Since you know the length of the lines in this scenario, you could jump to line N by simply doing
fseek(fp1, S * N, SEEK_SET);
where N is the line number (starting at 0) and S is the length of the line (as mentioned above, 8 bytes in our example file).
Note that the second solution will break if you're using a multi-byte encoding such as Unicode. Keep that in mind.
Using fgets() i made program, try it.
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp1, *fp2;
char ch,*str,*r;
int i =0;
int n = 0;
int l;
fp1 = fopen("co.data", "r");
fp2 = fopen("Output.txt", "w+");
printf("please enter how many lines do not need to be copied\n");
scanf ("%d", &l);
while (1)
{
if(r=fgets(str, 500, fp1))
{ /* a loop to read/copy the file*/
i++;
}
if (r == NULL)
break;
else if (i > l)
fputs(str, fp2);
}
printf("File copied Successfully!\n");
printf("number of lines read is %d\n",i-1);
printf("number of lines copied is %d\n",i-1-l);
fclose(fp1);
fclose(fp2);
}
I'm trying to figure out how to read a file that contains different variable types. In this case the .txt file is formatted like this.
MCD
McDonald's
20.45
BK
Burger King
30.47
DQ
Dairy Queen
25.63
It goes in a pattern of two strings followed by a double. My code to read in the file is as follows
int fillArray(struct Stock * array, FILE * fin)
{
int i = 0;
char buff[MAX];
while(fgets(buff, MAX, fin) != NULL)
{
strcpy(array[i].symbol, buff);
fgets(buff, MAX, fin);
strcpy(array[i].companyName, buff);
fscanf(fin, "%lf", &array[i].currentPrice);
i++;
}
return i;
}
When I go to print the structure I get this output.
MCD
McDonald's
20.45
BK
0.00Burger Kin30.47
30.47
0.00DQ
Dairy Queen
25.63
0.00
It seems things fall apart as soon as a string with spaces is read. Does anyone know what might be causing this? Thanks.
After the number is read using
fscanf(fin, "%lf", &array[i].currentPrice);
the newline character is still there in the input stream. The next call to fgets() reads only the newline into the array.
Add the following to skip till the end of the line after that.
int c;
while ( ( c = fgetc(stdin)) != EOF && c != '\n');
So i'm trying to write a function that will read number of lines in a text file. However, I notice that the function will not exit even when it exceeded number of lines in my text file. Why? Why does it work when i put
fgets(sentence, 70, inputFile);
before counter ++
int GetNumLine(char *fileName){
FILE *inputFile;
//counter are used to store number of lines
int counter = 0;
char sentence [70];
inputFile = fopen(fileName,"r");
//if there are anything wrong with inputfile
if(inputFile == NULL){
printf("Error while opening file");
exit(1);
}
while(!feof(inputFile) ){
counter++;
}
fclose(inputFile);
return counter;
}
This will be always true
while(!feof(inputFile))
you need to read from the file in order to reach the end and the EOF marker be set, i'd recommend doing it this way
int chr;
while ((chr = fgetc(inputFile)) != EOF)
counter += (chr == '\n') ? 1 : 0;
when you put fgets() before counter++ you read from the file and change the position in the FILE * structure, when you try to read beyond the end of the file, EOF will be set and feof(inputFile) will return non-zero.
The code with the fgets() works but is not robust because you can have a line with more than 69 characters and it will be counted twice, with my suggestion the result will be always correct.
I'm having a problem with a program (part of a program). To proceed any further I need to somehow read a line of a file but that must be a specific line.
I'm really new to C and files...
What I'm trying to do, is to ask the user to enter the specific line they want to read and then display it to them.
At the moment, when I try to print the text from the line it gives me text from line 1 only. Please note that by text I mean integers since the file consists of 55 integers in one column.
So it looks like this:
12
18
54
16
21
64
.....
Is there any way to achieve what I need?
#include <stdio.h>
FILE *file;
char name[15];
int line;
int text;
file = fopen("veryimportantfile.txt","r");
if(file==NULL)
{
printf("Failed to open");
exit(1);
}
printf("Your name: ");
scanf("%s",&name);
printf("\Enter the line number you want to read: ");
scanf("%d",&line);
fscanf(pFile, "%d", &line);
printf("The text from your line is: %d",line);
How about:
Read characters from the file, one by one, using getc, until you encounter the required number of newlines minus 1
Read integers using a loop and fscanf("%d", ...)
Something like:
int ch, newlines = 0;
while ((ch = getc(fp)) != EOF) {
if (ch == '\n') {
newlines++;
if (newlines == line - 1)
break;
}
}
if (newlines != line - 1)
/* Error, not enough lines. */
/* fscanf loop */
Hey I have been trying to count the number of words in my text file, to load up a bunch of words for a Hangman game, from C but I am hitting a brick wall. This piece of code I am using is supposed I am using this piece of code;
FILE *infile;
FILE *infile;
char buffer[MAXWORD];
int iwant, nwords;
iwant = rand() %nwords;
// Open the file
infile = fopen("words.txt", "r");
// If the file cannot be opened
if (infile ==NULL) {
printf("The file can not be opened!\n");
exit(1);
}
// The Word count
while (fscanf(infile, "%s", buffer) == 1) {
++nwords;
}
printf("There are %i words. \n", nwords);
fclose(infile);
}
If anyone has anyone has any suggestions on how to fix this I would be very grateful.
The text file has 1 word per line, with 850 words.
Applied the buffer suggestion, however the word count still came out at 1606419282.
The correction of putting
int nwords = 0;
Worked!! Thank you very much!
So the words are one entry per line?
while (fscanf(infile, "%s", &nwords) == 1); {
++nwords;
}
Doesn't do what you think it does. It reads a string in nwords, which isn't a string.
If you want to do it like this then you need to allocate a string ie char buffer[XXX] which is long enough to contain the longest lien in your data file and use:
while (fscanf(infile, "%s", buffer) == 1) {
++nwords;
}
The variable nwords is never initialized. You cannot assume it to start out as zero.
If it were, you'd get a crash ("divide by zero") on the next line, whose purpose eludes me:
iwant = rand() %nwords;
So, replace
int iwant, nwords;
iwant = rand() %nwords;
by
int nwords = 0;
After reading the first word and whitespace after it, your fscanf RETURNS to input buffer the whitespace. So, the next time you read EMPTY word.
Change proposed:
fscanf(infile, "%s ", &buffer) // notice the space!!! And & before buffer
It will throw off ALL whitespace till the next word. It should work.
P.S. Better not use [f]scanf :-)