I'm trying to read through a text file and using a for loop to do so as follows:
FILE *in = fopen("sim_input.txt", "r");
FILE *temp = in;
for (char c = getc(temp); c != EOF; c = getc(temp))
{
fscanf(in, "%d %d\n", &A[in].from, &A[in].to);
}
The problem is that the getc() is messing with the file stream and fscanf(). I tried creating a temp file to divert the stream but that didn't work.
The text file contains.
1 10
4 20
5 14
6 7
8 1
4 5
10 14
And it's coming out as:
10 4
1 5
4 6
etc
How can I stop this from happing.
I think you want this:
while (fscanf(in, "%d %d\n", &A[in].from, &A[in].to) != EOF)
{
// empty block
}
or this:
do
{
fscanf(in, "%d %d\n", &A[in].from, &A[in].to);
}
while (!feof(in));
Your attempt of using temp instead of in for the getc is pointless as temp and in refer to the exact same FILE object.
Bonus hint
Another thing that is absolutely essential is checking if fopen fails:
FILE *in = fopen("sim_input.txt", "r");
if (in == NULL)
{
// take action if file could not be opened
}
else
{
// process file
}
In your code if the file does not exist or cannot be opened for whatever other reason you will fscan from a NULL FILE pointer which usually doesn't end well.
Related
I should write a program that reads a set of set of numbers from a file and performs the computation of mean, standard deviation on each set. After each computation it will write the computed values to a new file in c language
#include <stdio.h>
int main()
{
char ch;
FILE *fpr, *fpw;
fpr = fopen("C:\\Users\\Hilal\\Desktop\\Data.txt", "r");
if (fpr == NULL) {
puts("Input file cannot be opened");
}
fpw = fopen("C:\\Users\\Hilal\\Desktop\\Output.txt", "w");
if (fpw == NULL) {
puts("Output file cannot be opened");
}
while (1) {
ch = fgetc(fpr);
if (ch == EOF)
break;
else
fputc(ch, fpw);
}
fclose(fpr);
fclose(fpw);
return 0;
}
I have no problem opening or writing the file. but I'm having trouble getting the set of numbers written on each line in the file one by one and dealing with each line separately.Like
Input: 4 47 -5 12 44/ 2 128 -127/ 1 17/
Output: 20.4 23.7/ 1 127.5/ 9 11.3/
The code you have provided echos the text from your input file to your output file. It does this character by character. What you're trying to do is go through your input file line by line. If you know how many numbers are on each input line, you could use a function like fscanf.
You can find usage examples here or, if you have access to a terminal, type in man fscanf.
I'm currently working on making a tiny computer in C for a programming assignment and I'm stuck on one part.
I'm stuck on how to correctly ignore comments in a text file that I'm reading in. (Example of file input below).
Input File
5 5 //IN 5
6 7 //OUT 7
3 0 //STORE 0
5 5 //IN 5
6 7 //OUT 7
3 1 //STORE 1
1 0 //LOAD 0
4 1 //SUB 1
3 0 //STORE 0
6 7 //OUT 7
1 1 //LOAD 1
6 7 //OUT 7
7 0 //END
The first input on each new line is an operation, the 2nd input being an address. I am planning to have a switch statement for each op and then calling the appropriate function. This is my current layout for reading in the file:
//file handling
int c;
FILE * file;
file = fopen(name, "r");
if (file){
printf("Run.\n");
while ((c = getc(file)) != EOF){
op = c;
switch (op){
case 5:
print("Inside case 5\n");
}
}
fclose(file);
}
How can I ignore the // on each line and skip to the next line in the file?
Call fgets to get a full line:
fgets(buffer, 100, file);
and then extract the two numbers from the line:
sscanf(buffer, "%d%d", &instruction, &address);
how to correctly ignore comments in a text file that I'm reading in
How can I ignore the // on each line and skip to the next line in the file?
Read the line using fgets()
char buf[80];
if (fgets(buf, sizeof buf, file)) {
Look for the // with strstr() #Steve Summit and lop off the string at that point.
char *slash_slash = strstr(buf, "//");
if (slash_slash) {
*slash_slash = '\0';
}
Continue processing the line as desired.
...
}
By using fgets and strtok you can read line by line and split the string acording to the // delimiter. Here's an example (it is not fully checked, but it's the main idea):
FILE *f = fopen("file.txt", "r");
if (f== NULL)
{
printf("opening file failed\n");
return 1;
}
char buf[256] = { 0 };
while (fgets(buf, 256, f))
{
char *s = strtok(buf, "//");
if (s == NULL)
{
printf("s == NULL\n");
}
else
{
printf("%s\n", s);
}
memset(buf, 0, 256);
}
fclose(f);
EDIT: I just realized that this is not exactly what you were looking for. However, you can still use it in order to first ignore the comment, and then break the given string into operation and address, or whatever that is...
I'm trying to overwrite a line in a file that contains only unsigned long numbers.
The contents of the file look like this:
1
2
3
4
5
I want to replace a specific number with the number 0. The code I wrote looks like this:
FILE *f = fopen("timestamps", "r+");
unsigned long times = 0;
int pos = 0;
while(fscanf(f, "%lu\n", ×) != EOF)
{
if(times == 3)
{
fseek(f, pos, SEEK_SET);
fprintf(f, "%lu\n", 0);
}
times = 0;
pos = ftell(f);
}
fclose(f);
f = fopen("timestamps", "r");
times = 0;
while(fscanf(f, "%lu\n", ×) != EOF)
{
printf("%lu\n", times);
times = 0;
}
fclose(f);
The output of the program looks like this:
1
2
10
5
Interestingly, if I cat the file, it looks like this:
1
2
10
5
Am I making a mistake in my ftell? Also, why didn't the printf show the missing line that the cat showed?
I could reproduce and fix.
The present problem is that when you open a file in r+ you must call fseek at each time you switch from reading to writing and from writing to reading.
Here, you correctly call fseek before writing the 0, but not after that write and the following read. The file pointer is not correctly positionned and you get undefined behaviour.
Fix is trivial, simply replace :
if(times == 3)
{
fseek(f, pos, SEEK_SET);
fprintf(f, "%lu\n", 0);
}
with
if(times == 3)
{
fseek(f, pos, SEEK_SET);
fprintf(f, "%lu\n", 0);
pos = ftell(f);
fseek(f, pos, SEEK_SET);
}
But BEWARE : it works here because you replace a line by a line of exactly same length. If you tried to replace a line containing 1000 with a line containing 0 you would get an extra line containing 0 on a windows system where end of line is \r\n and 00 on an unix like system with end of line \n.
Because here is what would happen (Windows case) :
Before rewrite :
... 1 0 0 0 \r \n ...
After :
... 0 \r \n 0 \r \n ...
because a sequential file is ... a sequential serie of byte !
The most comfortable way (in my opinion) to change text files is to create a new temporary file, copy the old one, line by line, with whatever changes you need, delete the old (or rename) and rename the temporary file.
Something like
char line[1000];
FILE *original, *temporar;
original = fopen("original", "r");
temporar = fopen("temporar", "w");
while (fgets(line, sizeof line, original)) {
processline(line);
fprintf(temporar, "%s", line);
}
fclose(temporar);
fclose(original);
unlink("original"); // or rename("original", "original.bak");
rename("temporar", "original");
Of course you need to validate all calls in real code.
I am trying to add a -1 to the end of each line of a file. For instance, file.txt is
1 4 5
2 5 9
3 5 6
but would become
1 4 5 -1
2 5 9 -1
3 5 6 -1
I am figuring out how to add text in general to a file from C, but I cannot figure out how to add the same text to each line in the file, and assure that the new line character is placed after the new last character in the lines (in this case -1).
Here is what I have tried:
FILE *f = fopen("file.txt", "w");
if (f == NULL)
{
printf("Error opening file!\n");
exit(1);
}
/* print some text */
const char *text = " -1";
fprintf(f, "%s\n", text);
Any advice greatly appreciated!
I can add -1 to each line using a text editor, by replacing "\r\n" with " -1\r\n" or similar depending on the file's eol format.
Or programmatically, create a new file like this:
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fr, *fw;
char buffer[10000];
fr = fopen("file.txt","rt");
if (fr == NULL) {
printf("Error opening input file\n");
return 1;
}
fw = fopen("file1.txt","wt");
if (fw==NULL) {
printf("Error opening output file\n");
fclose (fr);
return 1;
}
while (fgets(buffer, 10000, fr) != NULL) {
buffer [ strcspn(buffer, "\r\n") ] = 0; // remove trailing newline etc
fprintf(fw, "%s -1\n", buffer);
}
fclose(fw);
fclose(fr);
return 0;
}
Output file:
1 4 5 -1
2 5 9 -1
3 5 6 -1
Simply read each char, one at a time and print the suffix when the end-of-line detected. Then print the character read.
void Append(FILE *inf, FILE *outf, const char *suffix) {
int ch;
for (;;) {
int ch = fgetc(inf);
if (ch == '\n' || ch == EOF) {
fputs(suffix, outf);
if (ch == EOF) {
break;
}
}
fputc(ch, outf);
}
}
// Error checking omitted
char tmp[L_tmpnam];
tmpnam(tmp);
FILE *inf = fopen("file.txt", "r");
FILE *outf = fopen(tmp, "w");
Append(inf, outf, " -1");
fclose(inf);
fclose(outf);
remove("file.txt");
rename(tmp, "file.txt");
If you agree to use two seperate files for input and output, your job will be very easy. The algorithm to achieve what you want can be designed like below
Open the input file, open the output file. [fopen()]
define a string with the constant input value that you want to add after each line. [char * constvalue = "-1";]
Read a line from the input file. [fgets()##]
use fprintf() to write the data read from the input file and the constant value, together. Some pseudocode may look like
fprintf(outfile, "%s %s", readdata, constvalue);
loop untill there is value in the input file [while (fgets(infile....) != NULL)]
close both the files. [fclose()]
## -> fgets() reads and stores the trailing newline \n to the supplied buffer. You may want to remove that.
I'm a student learning C for the first time. I typed in an example the professor gave the class, which is supposed to read in some integers from a file called "input.txt".
Here's the code:
#include <stdio.h>
int main() {
FILE *ifp;
int num = -1, sum = 0;
ifp = fopen("input.txt", "r");
while (num!= 0) {
fscanf(ifp, "%d", &num);
sum +=num;
}
fclose(ifp);
printf("The sum is %d.\n", sum);
return 0;
}
I'm trying to get this program to print out the "sum" like it should, but when I run it, there are no errors yet the only output I get is (11db).
I created a file called "input.txt" and saved it to the desktop, but it's not working.
The file "input.txt" contains:
1
2
3
4
5
I don't know if I'm supposed to somehow, somewhere, define the file path or where/how to do this.
Any help is much appreciated.
Thanks!
My guess would be that the error is because opening the file fails. You should check that fopen returns non-NULL. Opening a file is an operation that often fails. For example:
ifp = fopen("input.txt", "r");
if (ifp == NULL) {
fprintf(stderr, "Couldn't open the file for reading.\n");
}
Unless given a full path name starting with a "/", fopen opens files in the current working directory of the process, and that is probably not the desktop.
Also, when you reach the end of the file, fscanf will return the value EOF. The variable num will not be set to zero. This is a way to read a file of integers:
while (fscanf(ifp, "%d", &num) == 1) {
sum += num;
}