File pointers led to core dump. Probably something stupid - c

Write the program myuniq.c that contains a function void process_file(FILE* f) that reads all input from the given file one line at the time while keeping two consecutive lines in memory, and prints each line to the standard output if it is not equal to the previously read line.
^^This is the assignment i'm working on. My code below is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void process_file(FILE* f);
int main()
{
FILE *fil = fopen("text.txt","r");
process_file(fil);
return 0;
}
void process_file(FILE* f)
{
FILE *fi = f;
char *firstLine = fgets(firstLine, 999, f);
char *secondLine = fgets(secondLine, 999, f);
while (feof(fi))
{
if (firstLine == secondLine)
{
puts(secondLine);
}
else
{
puts(firstLine);
puts(secondLine);
}
firstLine++;
secondLine++;
}
}
It compiled fine...but on every run it says core dumped. I can't see where I went wrong? Any ideas?

You don't check the return value of fopen, you don't allocate any memory for the strings into which you read, you don't continue reading input from the file, you don't correctly check for the end of input.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MY_MAX_LINE 999
void process_file(FILE* f)
{
char firstLine[MY_MAX_LINE + 1];
char secondLine[MY_MAX_LINE + 1];
while (1)
{
if (!fgets(firstLine, sizeof(firstLine), f))
break;
puts(firstLine);
if (!fgets(secondLine, sizeof(secondLine), f))
break;
if (strncmp(firstLine, secondLine, sizeof(firstLine)))
puts(secondLine);
}
if (!feof(f))
perror("Problem reading from file"), exit(1);
}
int main(int argc, char **argv)
{
FILE *f = fopen("text.txt", "r");
if (!f)
perror("text.txt"), exit(1);
process_file(f);
fclose(f);
return 0;
}

Related

How to read line by line using system call in C

In my program, I can currently read char by char a file with given name "fichier1.txt", but what I'm looking for is to store a line(line char pointer here) and then display it that way :
-ligne 1 : content line 1
-line 2 : content line 2
-ect...
I've tried to store char by char but since it's a pointer and I'm yet that much familiar with pointers I'm not able to store a line and then reuse the pointer to store the char of the next line.
I have to say that it's part of a school projet and I have to use POSIX standard.
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include <pthread.h>
#include<string.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
int read_fd, write_fd;
off_t offset = 0;
char lu;
struct stat statFd;
char *fichier = "fichier1.txt";
read_fd = open(fichier,O_RDONLY);
stat(fichier, &statFd);
if(read_fd == -1){
perror("open");
exit(EXIT_FAILURE);
}
int i = 0;
char * line; // variable to store line
while(lseek(read_fd,offset, SEEK_SET) < statFd.st_size)
{
if(read(read_fd, &lu, 1) != -1)
{
printf("%c",lu);
offset++;
} else {
perror("READ\n");
close(read_fd);
close(write_fd);
exit(EXIT_FAILURE);
}
}
return 0;
}
I'd like to use open() function and not fopen()
Since you are able to read character after character from the file, the logic in while loop will be used to store an entire line (up to 199 characters, you can increase it though) at once in an array & then display it:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
FILE *fptr=fopen( "fichier1.txt","r");
int i;
char arr[200]; //THIS ARRAY WILL HOLD THE CONTENTS OF A LINE TEMPORARILY UNTIL IT IS PRINTED
int temp_index=0,line_number=1;;
memset(arr,'\0',sizeof(arr));
while((i=getc(fptr))!=EOF)
{
if(i!='\n')
{
arr[temp_index++]=i;
}
if(i=='\n')
{
printf(line %d: %s\n",line_number++,arr);
temp_index=0;
memset(arr,'\0',sizeof(arr));
}
}
return 0;
}
Calling lseek at every iteration may be inefficient and may fail on devices which are incapable of seeking. I would write a program along these lines below if I don't need to store lines.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int lc = 0; /* line count */
int c; /* character read */
FILE *fp = fopen("fichier1.txt", "r");
if (fp == NULL) {
perror("fopen");
return EXIT_FAILURE;
}
while ((c = fgetc(fp)) != EOF) {
printf("line %d: ", ++lc);
while (c != '\n' && c != EOF) {
putchar(c);
c = fgetc(fp);
}
putchar('\n');
}
return 0;
}
Or, a program using fgets to read a line at once:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int main (void)
{
int lc = 0; /* line count */
char buf[4096]; /* buffer to store the line read */
bool newline = true;
FILE *fp = fopen("fichier1.txt", "r");
if (fp == NULL) {
perror("fopen");
return EXIT_FAILURE;
}
while (fgets(buf, sizeof buf, fp) != NULL) {
if (newline)
printf("line %d: ", ++lc);
printf("%s", buf);
newline = strchr(buf, '\n');
}
return 0;
}

C fread/fwrite behaves weird when dealing with newlines

I am currently trying to create a binary byte patcher but got stuck at one little issue.
When trying to read the input file byte by byte and simultanously writing these bytes to an output file, newline characters are somehow doubled.
An input like that:
line1
line2
line3
Would look like:
line1
line2
line3
 
The actual program is a bit more complex but this abstract should give an idea of what I'm trying to do.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SECTOR 32
int main(int argc, char** argv) {
FILE* input = fopen(INPUT_FILE, "r");
FILE * output = fopen(OUTPUT_FILE, "w");
int filesize = size of opened file...
char buffer[16] = {0};
int i = 0;
while(i < filesize) {
fseek(input, i, SEEK_SET);
fread(buffer, sizeof(char), SECTOR, input);
if(cmp buffer with other char array) {
do stuff
} else {
i++;
fwrite(&buffer[0], sizeof(char), 1, output);
}
}
print rest of buffer to the file to have the past SECTOR-1 bytes aswell...
fclose(input);
fclose(output);
return 1;
}
Try to use open,close,read ans write instead of fopen fread fwrite and fclose. You should get something like that:
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define BUFFSIZE 32
int main(int argc, char** argv) {
int input = open(INPUT_FILE, O_RDONLY);
int output = open(OUTPUT_FILE, O_WRONLY | O_CREATE, S_IWUSR | S_IRUSR);
int i = 0;
char buffer[BUFFSIZE];
while((i = read(input, buffer, BUFFSIZE))) {
if(cmp buffer with other char array) {
do stuff
} else {
while (i < 0) {
i--;
write(output, &buffer[i], sizeof(char));
}
}
}
close(input);
close(output);
return 1;
}

C number of characters on file

Why is my program returning me 9 when the file has "test1" written?
The program looks for number of characters within the file. I wanted to run off the 'while(fgetc(file) != EOF)' method but this seems not to be working.
I would appreciate some help on this. Thank you
#include <stdio.h>
#include <stdlib.h>
#define FORMATLOG "FORMAT ERROR: invalid parameter: s5e4 <filename.txt>"
#define TXFILELOG "FILE ERROR: Can't open file or file does not exist"
enum { true, false };
int interface(char *filename) {
FILE *f_text = fopen(filename, "r+");
size_t size;
char c;
if(f_text == NULL) {
puts(TXFILELOG);
return NULL;
}
fseek(f_text, 0, SEEK_END);
size_t length = (size_t) ftell(f_text);
printf("%d", length);
fclose(f_text);
return true;
}
int main(int argc, char **argv) {
if(argc != 2) {
puts(FORMATLOG);
return false;
}
return interface(argv[1]);
}
Why the complication??
See http://linux.die.net/man/2/stat
i.e.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
struct stat buf;
stat("filename", &buf);
printf("Size:%d\n", buf.st_size);
return 0;
}
(oops missed out the error check but I guess you get the picture)

Converting Greek words to uppercase

I have to create a function that reads a file called grwords.txt containing around 540000 words which are written in Greek letters.
I have to convert these words to uppercase and fill an array called char **words.
This is what I have so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <ctype.h>
void fp();
int main(int argc, char *argv[]) {
SetConsoleOutputCP(1253);
fp();
return 0;
}
void fp(){
char **words;
words = malloc(546490 * sizeof(int *));
for (i = 0; i < 546490; i++)
words[i] = malloc(24 * sizeof(int));
FILE *file;
char *word;
size_t cnt;
file = fopen("grwords.txt", "rt");
if (file == NULL){
printf("File cannot be opened.\n");
exit(1);
}
cnt = 0;
while (1==fscanf(file, "%24s",word)){
if (cnt == 546490)
break;
strcpy(words[cnt++], word);
}
fclose(file);
}
I'm still trying to figure out pointers. I know that & makes a pointer from a value and * a value from a pointer. Updated the program and it successfully fills the array with the words from the file! I still have no idea how to convert Greek lowercase to uppercase.
Handling Greek words can be dependent on your platform.
First of all, you need to understand how file handling works. Here is what I wrote:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define bufSize 1024 // max lenght of word
// we are going to receive the .txt from cmd line
int main(int argc, char *argv[])
{
FILE *fp;
// Assume file has max 10 words
const size_t N = 10;
// Allocate a 2D array of N rows
// and bufSize columns.
// You can think of it like an array
// of N strings, where every string
// has, at most, bufSize length.
char buf[N][bufSize];
// make sure we got the .txt
if (argc != 2)
{
fprintf(stderr,
"Usage: %s <soure-file>\n", argv[0]);
return 1;
}
// open the file
if ((fp = fopen(argv[1], "r")) == NULL)
{ /* Open source file. */
perror("fopen source-file");
return 1;
}
// we will use that for toupper()
char c;
// counters
int i = 0, j;
while (fscanf(fp, "%1024s", buf[i]) == 1)
{ /* While we don't reach the end of source. */
/* Read characters from source file to fill buffer. */
// print what we read
printf("%s\n", buf[i]);
j = 0;
// while we are on a letter of word placed
// in buf[i]
while (buf[i][j])
{
// make the letter capital and print it
c = buf[i][j];
putchar (toupper(c));
j++;
}
i++;
printf("\ndone with this word\n");
}
// close the file
fclose(fp);
return 0;
}
For this test.txt file:
Georgios
Samaras
Γιώργος
Σαμαράς
the code would run as:
./exe test.txt
Georgios
GEORGIOS
done with this word
Samaras
SAMARAS
done with this word
Γιώργος
Γιώργος
done with this word
Σαμαράς
Σαμαράς
done with this word
As you can see, I could read the Greek words, but failed to convert them in upper case ones.
Once you got how file handling goes, you need to use wide characters to read a file with Greek words.
So, by just modifying the above code, we get:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>
#define bufSize 1024
int main(int argc, char *argv[])
{
setlocale(LC_CTYPE, "en_GB.UTF-8");
FILE *fp;
const size_t N = 15;
wchar_t buf[N][bufSize];
if (argc != 2)
{
fprintf(stderr,
"Usage: %s <soure-file>\n", argv[0]);
return 1;
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
perror("fopen source-file");
return 1;
}
wchar_t c;
int i = 0, j;
while (fwscanf(fp, L"%ls", buf[i]) == 1)
{
wprintf( L"%ls\n\n", buf[i]);
j = 0;
while (buf[i][j])
{
c = buf[i][j];
putwchar (towupper(c));
j++;
}
i++;
wprintf(L"\ndone with this word\n");
}
fclose(fp);
return 0;
}
And now the output is this:
Georgios
GEORGIOS
done with this word
Samaras
SAMARAS
done with this word
Γιώργος
ΓΙΏΡΓΟΣ
done with this word
Σαμαράς
ΣΑΜΑΡΆΣ
done with this word
I see that you may want to create a function which reads the words. If you need a simple example of functions in C, you can visit my pseudo-site here.
As for the 2D array I mentioned above, this picture might help:
where N is the number of rows (equal to 4) and M is the number of columns (equal to 5). In the code above, N is N and M is bufSize. I explain more here, were you can also found code for dynamic allocation of a 2D array.
I know see that you are on Windows. I tested the code in Ubuntu.
For Windows you might want to take a good look at this question.
So, after you read all the above and understand them, you can see what you asked for with dynamic memory management.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>
#define bufSize 1024
wchar_t **get(int N, int M);
void free2Darray(wchar_t** p, int N);
int main(int argc, char *argv[])
{
setlocale(LC_CTYPE, "en_GB.UTF-8");
FILE *fp;
const size_t N = 15;
wchar_t** buf = get(N, bufSize);
if (argc != 2)
{
fprintf(stderr,
"Usage: %s <soure-file>\n", argv[0]);
return 1;
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
perror("fopen source-file");
return 1;
}
wchar_t c;
int i = 0, j;
while (fwscanf(fp, L"%ls", buf[i]) == 1)
{
wprintf( L"%ls\n", buf[i]);
j = 0;
while (buf[i][j])
{
c = buf[i][j];
putwchar (towupper(c));
j++;
}
i++;
wprintf(L"\ndone with this word\n");
}
fclose(fp);
// NEVER FORGET, FREE THE DYNAMIC MEMORY
free2Darray(buf, N);
return 0;
}
// We return the pointer
wchar_t **get(int N, int M) /* Allocate the array */
{
/* Check if allocation succeeded. (check for NULL pointer) */
int i;
wchar_t **table;
table = malloc(N*sizeof(wchar_t *));
for(i = 0 ; i < N ; i++)
table[i] = malloc( M*sizeof(wchar_t) );
return table;
}
void free2Darray(wchar_t** p, int N)
{
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
Note that this code is expected to work on Linux (tested on Ubuntu 12.04), not on Windows (tested on Win 7).

Reading Text In C

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 500
int main(){
int JourneyId;
char Date[MAX];
int Hour;
char BusDriver[MAX];
char Departure[MAX];
char Destination[MAX];
int BusCapacity;
FILE * file;
file = fopen( "Journey.txt" , "rt");
if(file){
while (fscanf(file,"%d,%s,%d,%20[^,],%20[^,],%20[^,],%d", &JourneyId,Date,&Hour,BusDriver,Departure,Destination, &BusCapacity) != EOF){
printf("%d,",JourneyId);
printf("%s",BusDriver);
}
}
else{
printf("Error");
}
return 1;
}
I want to read text file and use this code for adding BST.But If I run , Output is infinite loop.How can I read text file ?
Text file which I want to read:
80,15.04.2014,10,Henry Ford,NewYork,Paris,45
40,15.04.2014,11,Nikola Tesla,Londra,NewYork,40
Rather than read a text file using fscanf(), strongly recommend using fgets() and then parsing via sscanf(), strtok(), strtol(), etc. Check all function return values. It is much easier to cope with the unexpected - which is certainly what is happening in OP's case.
Using modified format from #BLUEPIXY
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 500
int main() {
int JourneyId;
char Date[MAX];
int Hour;
char BusDriver[MAX];
char Departure[MAX];
char Destination[MAX];
int BusCapacity;
FILE * file;
file = fopen("Journey.txt", "rt");
if (file) {
char buf[MAX*4 + 20*3 + 6*1 + 3];
while (fgets(buf, sizeof buf, stdin) != NULL) {
int cnt = sscanf(buf, "%d,%499[^,],%d,%499[^,],%499[^,],%499[^,],%d",
&JourneyId, Date, &Hour, BusDriver, Departure, Destination,
&BusCapacity);
if (cnt != 7) {
printf("Unexpected input \"%s\"", buf);
break;
}
printf("%d,", JourneyId);
printf("%s\n", BusDriver);
}
fclose(file); // Be sure to close
} else {
printf("Error opening\n");
}
return 1;
}
As #BLUPIXY indicated, The following functions (tried on SuSE Linux / gcc)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 500
int main(){
int JourneyId;
char Date[MAX];
int Hour;
char BusDriver[MAX];
char Departure[MAX];
char Destination[MAX];
int BusCapacity;
FILE *file;
file = fopen( "Journey.txt" , "rt");
if(file)
{
// while(fscanf(file,"%d,%s,%d,%20[^,],%20[^,],%20[^,],%d", &JourneyId,Date,&Hour,BusDriver,Departure,Destination, &BusCapacity) != EOF){
while(fscanf(file,"%d,%11[^,],%d,%20[^,],%20[^,],%20[^,],%d", &JourneyId,Date,&Hour,BusDriver,Departure,Destination, &BusCapacity) != EOF){
printf("%d,",JourneyId);
printf("%s",BusDriver);
}
}
else
{
printf("Error");
}
return 1;
}

Resources