Reading a text file and ignoring commented lines in C - c

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...

Related

problem for program to read n last lines from file in c

I have a problem on my code which return the n last line from file, when I enter 8 it return 4 lines, 6 -> 3 last lines, 4 -> 2 last line and so on.
this is my code:
FILE* file;
int count = 0;
int pos;
char s[1000];
int numberOfline;
printf("Enter the number of last line to return: ");
scanf_s("%d", &numberOfline);
file = fopen("lines.txt", "rt+");
if (file == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
fseek(file, 0, SEEK_END);
pos = ftell(file);
while (pos) {
fseek(file, --pos, SEEK_SET);
if (fgetc(file) == '\n') {
if (count++ == numberOfline) break;
}
}
while (fgets(s, sizeof(s), file) != NULL) {
printf("%s", s);
}
fclose(file);
what is the problem and why he accept only even number and return the half of it, and how can i fix that?
Undefined behavior
fseek() on a text file is well defined for the beginning and positions from previous ftell().
OP is attempting an fseek() from every file position.
OP's woe of double counting is that an fget() sees "\r\n: and "\n: both as '\n.

Reading through File with temp file in C

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.

How do I read integers line by line from stdin until an empty line is found then store these integers into an array in c?

I am trying to read ints from stdin line by line and store this into an array. I will know that I am done reading input when I get an empty line. However, when I run this code I don't seem to be exiting the loop because the program just hangs. What am I doing wrong here?
int *nums;
const int datacount = 10000;
nums = malloc(sizeof(int) * datacount);
if (!nums) {
perror("Error allocating memory");
abort();
}
memset(nums, 0, sizeof(int)*datacount);
int cnt = 0;
char line[64];
while ((fgets(line, sizeof line, stdin) != NULL) && (line[0] !='\n') ) {
if (sscanf(line, "%d", &nums[cnt]))
{
cnt++;
fflush(stdout);
}
}
Program will hang on sample input:
1
6
5
4
2
3
8
7
\n

Add same text to end of each line in file from C

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.

Having issues with fwrite and fgets processing it

char string[50], s[50];
File *f = tmpfile();
count = 1;
while (fgets(string, 50, stdin)) {
if (string[0] == '!') {
rewind(f);
} else {
fwrite(string, 50, 1, f);
}
if (strcmp("history\n", string) == 0) {
rewind(f);
while(fgets(s, 50, f)) {
printf("\t%d %s", count, s);
count++;
}
count = 1;
}
}
The context of this code is not hugely important. The problem is that let's say fgets takes in "ls", "date", and "history". The resulting output is:
1 ls
2 3 te
4 5 ory
6
It should be:
1 ls
2 date
3 history
Since feature requests to mark a comment as an answer remain declined, I copy the above solution here.
Looks like you get some '\r's in your buffer. And you should probably only fwrite strlen(string) bytes. – Daniel Fischer

Resources