C programming: Error printing last line from an input file - c

I want to print an integer from 6th column of last line of an input file "out".
Following is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int len = 0;
int n2 = 0;
int n3 = 0;
char line[1000];
char *pch;
char c[6] = "ATOM ";
FILE *fp = fopen("1PGB.pdb", "r");
FILE *op = fopen("out", "w");
if (fp == NULL || op == NULL) {
fprintf(stderr, "Error opening file.\n");
exit(1);
} else {
while (fgets(line, sizeof(line), fp) != 0)
if ((pch = strstr (line, c)) != NULL)
fprintf(op, "%s\n", line);
}
fclose(fp);
fclose(op);
FILE *ip = fopen("out", "r");
fseek(ip, 1, SEEK_END);
if (fgets(line, len, ip) != NULL)
puts(line);
else
printf("Error\n");
fclose(ip);
}
It is expected to return the last line of the file "out".
It gives output: Error
The last few lines of the file out are:
ATOM 427 N GLU A 56 7.248 9.043 7.175 1.00 16.36 N
ATOM 428 CA GLU A 56 6.283 8.177 6.480 1.00 19.22 C
ATOM 429 C GLU A 56 6.780 7.744 5.081 1.00 22.26 C
ATOM 430 O GLU A 56 7.521 8.520 4.401 1.00 23.58 O
ATOM 431 CB GLU A 56 4.960 8.864 6.307 1.00 19.26 C
ATOM 432 CG GLU A 56 4.093 8.873 7.512 1.00 19.10 C
ATOM 433 CD GLU A 56 2.702 9.417 7.201 1.00 18.54 C
ATOM 434 OE1 GLU A 56 2.544 10.440 6.499 1.00 18.16 O
ATOM 435 OE2 GLU A 56 1.737 8.791 7.641 1.00 20.42 O
ATOM 436 OXT GLU A 56 6.410 6.617 4.667 1.00 24.74 O
And I want to print the integer "56" in 6th col of the last line.

output file omitted:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int len = 0;
int n2 = 0;
int n3 = 0;
int result=0;
char line[1000];
char lastline[1000]="";
char *pch;
char c[6] = "ATOM ";
FILE *fp = fopen("1PGB.pdb", "r");
//FILE *op = fopen("out", "w");
if (!fp) {
fprintf(stderr, "Error opening file.\n");
exit(1);
} else {
while (fgets(line, sizeof(line), fp) != 0)
if ((pch = strstr (line, c)) != NULL){
strcpy(lastline,line); //save content of the last output
printf("%s", line);
}
}
fclose(fp);
if(*lastline){
strtok(lastline," "); //skip first field
for(int i=0;i<4;i++) // skip next 4 fields (5 in total)
strtok(NULL," ");
sscanf(strtok(NULL," "),"%d",&result);//get and convert the 6th field
printf("LastLine: %d\n",result); //print it
}
return 0;
}

Related

Store data from columns of a text file to an array. in C

I have a text file that looks like this:
Process Priority Burst Arrival
1 8 15 0
2 3 20 0
3 4 20 20
4 4 20 25
5 5 5 45
6 5 15 55
7 9 10 70
8 6 15 100
9 5 15 105
10 5 15 115
The columns are separated by tabs.
I need to ignore the first line and then all entries from one column store them into an array such as "int process[10]".
I have found this thread :Reading in a specific column of data from a text file in C , however the way is done is very specific to the way the data is set up in the op's question.
thanks.
Give this a try. This grabs all columns you have from the file and is compliant with ansi:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parseLine(char *line, int *num1, int *num2, int *num3, int *num4 ){
char* temp;
temp = strchr(line,'\t');
temp[0] = '\0';
*num1 = atoi(line);
line = temp + 1;
temp = strchr(line, '\t');
temp[0] = '\0';
*num2 = atoi(line);
line = temp + 1;
temp = strchr(line, '\t');
temp[0] = '\0';
*num3 = atoi(line);
line = temp + 1;
*num4 = atoi(line);
}
int main(void)
{
FILE* fp;
char line[100];
int process[10];
int priority[10];
int burst[10];
int arrival[10];
int i;
int j;
i = 0;
if ((fp = fopen("./yourfile.txt", "r")) == NULL)
{
printf("Error Opening File\n");
exit(1);
}
fgets(line, sizeof(line), fp);
while (fgets(line, sizeof(line), fp))
{
parseLine(line, &process[i],&priority[i],&burst[i],&arrival[i]);
i++;
}
for (j = 0; j < 10; j++){
printf("Process: %d, Priority: %d, Burst: %d, Arrival: %d\n", process[j], priority[j], burst[j], arrival[j]);
}
fclose(fp);
return 0;
}
First a note on this, is not a complete solution but I think it will help you with the parsing of the file. Also instead of
store them into an array such as "int process[10]"
I think it would better to store them on a dynamic array, otherwise you would need to know, before hand, the numbers of line of the column, that you are trying to extract. This code only parse the file given your format and print the values of the first column, I think can be adapted to your situation after you implement the dynamic array so here it is:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/*scan_file: read each of the lines of the file.*/
int scan_file(char *filename)
{
char *line_buf = NULL;
size_t line_buf_size = 0;
ssize_t line_size;
char *next = NULL;
FILE *fp = fopen(filename, "r");
if (!fp) {
fprintf(stderr, "Error opening file '%s'\n", filename);
return 1;
}
/*Get the first line of the file and do nothing with it*/
line_size = getline(&line_buf, &line_buf_size, fp);
while (line_size > 0)
{
//second and subsecuent lines
line_size = getline(&line_buf, &line_buf_size,fp);
if (line_size <= 0)
break;
line_buf[line_size-1] = '\0'; /*removing '\n' */
char *part = strtok_r(line_buf, " ", &next);
if (part)
printf("NUMBER: %s\n", part);
}
// don't forget to free the line_buf used by getline
free(line_buf);
line_buf = NULL;
fclose(fp);
return 0;
}
int main(void)
{
scan_file("file.txt");
return 0;
}
NOTE: Here I assume that the file is called file.txt you should change it for the name of your file.
OUTPUT:
NUMBER: 1
NUMBER: 2
NUMBER: 3
NUMBER: 4
NUMBER: 5
NUMBER: 6
NUMBER: 7
NUMBER: 8
NUMBER: 9
NUMBER: 10
I put it in this way so you could identify the line printf("NUMBER: %s\n", part);, here you could change it to something that push this value into the dynamic array.

Writing half of an int array into a new text file

In my program, I am trying to opens the text file provided at the command-line, and then creates two new text files values1.txt and values2.txt. The file from the command line contains 100 unique integer numbers. Half of the numbers are copied into values1.txt, the other half is copied into values2.txt.
However, when I tried to do it for values1.txt, I got the following values:
101
32758
0
0
176197744
32764
3
0
176197728
32764
0
0
-78325960
32758
0
0
1
0
-78326000
32758
0
0
1700966438
0
-78325096
32758
176197896
32764
176197952
32764
-78326000
32758
0
0
-80547345
32758
0
0
176197952
32764
0
0
0
0
0
0
-78326000
32758
-82942073
32758
8
Here is my code:
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
int cfileexists(const char * filename){
/* try to open file to read */
FILE *file;
if (file = fopen(filename, "r")){
fclose(file);
return 1;
}
}
int main(int argc,char*argv[]){
char *p= argv[1];
int numArray[100];
int i=0;
int sum1arr[50];
int sum2arr[50];
if (! cfileexists(p)){
printf("Error, unable to locate the data file %s\n", p);
return 100;
}
for(i;i<100;i++){
FILE *stream=fopen(p,"r");
while(!feof(stream)){
fscanf(stream,"%d",&numArray[i]);
}
FILE * fPtr = NULL;
fPtr = fopen("values1.txt", "w");
for(int j=0;j<50;j++){
fprintf(fPtr,"%d\n",numArray[j]);
}
}
}
For comparison; this is the source txtfile:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
The for statement has too many cycles, you should use the read cycle to also write, you also can use fscanf return to verify whe the file reaches it's end. If you don't need to save the values you can even use on singe int to temporarily store the value till it's written.
Here is a possibe implementation with comments:
Live demo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cfileexists(const char *filename)
{
/* try to open file to read */
FILE *file;
if ((file = fopen(filename, "r")))
{
fclose(file);
return 1;
}
return 0; //return 0 if file not found
}
int main(int argc, char *argv[])
{
if(argc != 2){ //check number of arguments
puts("Wrong number of arguments");
return(EXIT_FAILURE); //EXIT_FAILURE macro is more portable
}
FILE *stream;
FILE *fPtr = NULL;
FILE *fPtr2 = NULL;
int numArray[100];
int i = 0;
fPtr = fopen("values1.txt", "w");
fPtr2 = fopen("values2.txt", "w");
//you can use fopen to check file nstead of the
//function, it returns null if no file is opened
if (!(stream = fopen(argv[1], "r")))
{
perror("Error, unable to locate the data file"); //also prints error signature
return EXIT_FAILURE;
}
//check input, stop when there is nothing else to read
while (fscanf(stream, "%d", &numArray[i]) == 1 && i < 100)
{
if(i < 50)
fprintf(fPtr, "%d\n", numArray[i]); //write to file 1
else
fprintf(fPtr2, "%d\n", numArray[i]); //write to file 2
i++;
}
fclose(stream);
fclose(fPtr);
fclose(fPtr2);
}
Here's a different approach that uses getline():
#include <stdio.h>
#include <stdlib.h>
#define SPLIT_POINT 50
int main(void) {
char filename[] = "test";
FILE *fp = fopen(filename, "r");
if (!fp) {
fprintf(stderr, "Couldn't open %s\n", filename);
}
// Check file open (as above) left out for brevity
FILE *out1 = fopen("values1.txt", "w");
FILE *out2 = fopen("values2.txt", "w");
char *line = NULL;
size_t n = 0, i = 0;
ssize_t len = 0;
while ((len = getline(&line, &n, fp)) != EOF) {
// Select which output file to write to
FILE *out = i < SPLIT_POINT ? out1 : out2;
// getline includes the newline - remove this
if (i == SPLIT_POINT - 1 && len > 0) {
line[--len] = 0;
}
// Write to the relevant output file
fprintf(out, "%s", line);
i++;
}
fclose(fp);
fclose(out1);
fclose(out2);
free(line);
return 0;
}
If you don't care about removing newlines, you could simplify the getline() call - just don't bother with the len variable.

Program does not suppress integers, although float numbers are suppressed

I have a txt file like that:
alter_ego,simulation,pc,1985,0,0.03,0.03,5.8
simcity,simulation,pc,1988,0,0.02,0.03,2.2
doom,shooter,pc,1992,0.02,0,0.03,8.3
star_wars:dark_forces,shooter,pc,1994,1.09,0.77,1.95,7.7
battle_arena_toshinden,fighting,ps,1994,0.39,0.26,1.27,6.3
resident_evil,action,ps,1996,2.05,1.16,5.05,9
using this code, I write in another file like this:
alter_ego
simulation
pc
1985
0
0.03
0.03
5.8
simcity
simulation
pc
1988
0
0.02
0.03
2.2
doom
shooter
pc
1992
0.02
0
0.03
8.3
star_wars:dark_forces
shooter
pc
1994
1.09
0.77
1.95
7.7
...
however, when the program reaches an integer, it does not write that number to the file.(
for example, the 9 files at the end of the resident evil are not printed.)
#include <stdio.h>
int main(void){
char line[128];
char word[32];
FILE *in, *out;
int line_length;
in = fopen("in.txt", "r");
out = fopen("out.txt", "w");
while(1==fscanf(in, "%[^\n]%n\n", line, &line_length)){//read one line
int pos, len;
for(pos=0;pos < line_length-1 && 1==sscanf(line + pos, "%[^,]%*[,]%n", word, &len);pos+=len){
fprintf(out, "%s\n", word);
}
}
fclose(out);
fclose(in);
return 0;
}
how can I fix it?Thanks...
That's easy.
Here is my code:
#include <stdio.h>
int main()
{
int c;
while((c = getchar()) != EOF){
if(c == ',' || c == '\n')
printf("\n");
else
printf("%c",c);
}
}
in file.txt
alter_ego,simulation,pc,1985,0,0.03,0.03,5.8
simcity,simulation,pc,1988,0,0.02,0.03,2.2
doom,shooter,pc,1992,0.02,0,0.03,8.3
star_wars:dark_forces,shooter,pc,1994,1.09,0.77,1.95,7.7
battle_arena_toshinden,fighting,ps,1994,0.39,0.26,1.27,6.3
resident_evil,action,ps,1996,2.05,1.16,5.05,9
then run command:
gcc -o print print.c
./print < file.txt
That's all.
pos < line_length-1
is wrong - it is omitting last character. Just:
pos < line_length
Tested with:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
char str[] =
"alter_ego,simulation,pc,1985,0,0.03,0.03,5.8\n"
"simcity,simulation,pc,1988,0,0.02,0.03,2.2\n"
"doom,shooter,pc,1992,0.02,0,0.03,8.3\n"
"star_wars:dark_forces,shooter,pc,1994,1.09,0.77,1.95,7.7\n"
"battle_arena_toshinden,fighting,ps,1994,0.39,0.26,1.27,6.3\n"
"resident_evil,action,ps,1996,2.05,1.16,5.05,9\n";
int main(void){
char line[128];
char word[32];
FILE *in = fmemopen(str, sizeof(str), "r");
FILE *out = stdout;
int line_length;
while (1 == fscanf(in, "%127[^\n]%n\n", line, &line_length)) {//read one line
int pos, len, r;
for (pos = 0; pos < line_length &&
1 == sscanf(line + pos, "%31[^,]%*[,]%n", word, &len);
pos += len){
fprintf(out, "%s\n", word);
}
}
fclose(in);
fclose(out);
return 0;
}

Read numbers from txt file second line in a C Array

I do have a txt file which looks like this
10
41 220 166 29 151 47 170 60 234 49
How can I read only the numbers from the second row into an array in C?
int nr_of_values = 0;
int* myArray = 0;
FILE *file;
file = fopen("hist.txt", "r+");
if (file == NULL)
{
printf("ERROR Opening File!");
exit(1);
}
else {
fscanf(file, "%d", &nr_of_values);
myArray = new int[nr_of_values];
// push values from second row to this array
}
How can I read only the numbers from the second row into an array in C?
Ignore the first line by reading and discarding it.
You could use something like that:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char const *filename = "test.txt";
FILE *input_file = fopen(filename, "r");
if (!input_file) {
fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
return EXIT_FAILURE;
}
int ch; // ignore first line:
while ((ch = fgetc(input_file)) != EOF && ch != '\n');
int value;
int *numbers = NULL;
size_t num_numbers = 0;
while (fscanf(input_file, "%d", &value) == 1) {
int *new_numbers = realloc(numbers, (num_numbers + 1) * sizeof(*new_numbers));
if (!new_numbers) {
fputs("Out of memory :(\n\n", stderr);
free(numbers);
return EXIT_FAILURE;
}
numbers = new_numbers;
numbers[num_numbers++] = value;
}
fclose(input_file);
for (size_t i = 0; i < num_numbers; ++i)
printf("%d ", numbers[i]);
putchar('\n');
free(numbers);
}

Reading from file in C including char and integer

How to read and store each column in the following text from a file into an array
A17ke4004 44 66 84
A17ke4005 33 62 88
A17ke4008 44 66 86
The first column should be string and the rest should be integer
Here is a simple code that do the job.
First put your text inside a test.txt file, save it in C source code path.
test.txt
A17ke4004 44 66 84
A17ke4005 33 62 88
A17ke4008 44 66 86
Code
#include <stdio.h>
int main (void)
{
FILE *fp = NULL;
char *line = NULL;
size_t len = 0;
size_t read = 0;
char string[10][32];
int a[10], b[10], c[10];
int count = 0;
fp = fopen("test.txt", "r");
if(fp != NULL){
while((read = getline(&line, &len, fp)) != -1){
sscanf(line, "%s%d%d%d", string[count], &a[count], &b[count], &c[count]);
printf("<%s> - <%d> - <%d> - <%d>\n", string[count], a[count], b[count], c[count]);
count++;
}
}else{
printf("File can't open\n");
}
return 0;
}
Compile, Run
gcc -Wall -Wextra te.c -o te
./te
If you have more than 10 lines you should increase the arrays dimension.
Hope this help you.

Resources