I have an archive results.csv and I need to read the first line of this archive and print it out on output.txt. Somehow it's printing random characters after everything and I couldn't figure out what is wrong.
Command: a.c results.csv
First line:
date,home_team,away_team,home_score,away_score,tournament,city,country,neutral
output.txt: date,home_team,away_team,home_score,away_score,tournament,city,country,neutral,(!£,(!£,(!£,(!£,(!£,#,£,(!£,(!£
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct
{
char *line1;
char *line1a;
char *line1b;
char *team1;
char *team2;
char *reason;
char *city;
char *country;
char *neutral_field;
}data;
void open_input(char *argv[], FILE **input)
{
if((*input=fopen(argv[1], "r")) == NULL)
{
printf("%s not found\n", argv[1]);
exit(1);
}
}
void open_output(char *string, FILE **output)
{
if((*output=fopen(string, "w")) == NULL)
{
printf("%s not found\n", string);
exit(1);
}
}
void alloc_data(data *d, int size)
{
d->line1 = (char*)malloc(4*sizeof(char));
d->team1 = (char*)malloc(9*sizeof(char));
d->team2 = (char*)malloc(9*sizeof(char));
d->line1a = (char*)malloc(10*sizeof(char));
d->line1b = (char*)malloc(10*sizeof(char));
d->reason = (char*)malloc(10*sizeof(char));
d->city = (char*)malloc(4*sizeof(char));
d->country = (char*)malloc(7*sizeof(char));
d->neutral_field = (char*)malloc(7*sizeof(char));
}
void store(data *d, FILE *input, FILE **output)
{
fscanf(input, "%s,%s,%s,%s,%s,%s,%s,%s,%s", d[0].line1, d[0].team1, d[0].team2, d[0].line1a, d[0].line1b, d[0].reason, d[0].city, d[0].country, d[0].neutral_field );
fprintf(*output, "%s,%s,%s,%s,%s,%s,%s,%s,%s\n", d[0].line1, d[0].team1, d[0].team2, d[0].line1a, d[0].line1b, d[0].reason, d[0].city, d[0].country, d[0].neutral_field );
}
int main(int argc, char *argv[])
{
FILE *input;
FILE *output;
char *string = "output.txt";
int size = 1000;
open_input(argv, &input);
open_output(string, &output);
data *d;
d = (data*)malloc(size*sizeof(data));
alloc_data(d, size);
store(d, input, &output);
free(d);
return 0;
}
fscanf(input, "%s,%s,%s,%s,%s,%s,%s,%s,%s", d[0].line1, d[0].team1,...
The above code tries to read the whole line in to d[0].line1 which causes buffer overflow. team1 and the rest will contain uninitialized data.
You have to change fscanf as follows:
fscanf(input, "%3[^ ,\n\t],%9[^ ,\n\t],...
Where 3 is 4 - 1, and 4 is the size of d[0].line1
Alternatively you can use strtok
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void store(FILE *input, FILE *output)
{
char buf[500];
while(fgets(buf, sizeof(buf), input))
{
//strip end-of-line from `buf`
if(strlen(buf))
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
//tokenize with strtok
char *token = strtok(buf, ",");
while(token)
{
fprintf(output, "%s", token);
token = strtok(NULL, ",");
}
fprintf(output, "\n");
}
}
int main(int argc, char *argv[])
{
FILE *input = fopen("input.txt", "r");
FILE *output = fopen("output.txt", "w");
store(input, output);
return 0;
}
With above code you don't need an additional structure.
If you do use a structure for data, you have to be more careful. It seems you are trying to create an array of 1000 data, but the following only creates one oversized pointer, not an array of data
int size = 1000;
data *d;
d = (data*)malloc(size*sizeof(data));
alloc_data(d, size);
Additionally, for each malloc there should be a corresponding free.
Your buffers aren't big enough to hold the terminating NUL byte. scanf stores that NUL byte (overrunning the buffer), but then the object that really owns that byte may overwrite it, so when printf looks for the NUL it doesn't find it until much later in memory.
The buffer overruns are a bigger problem than what you've seen, who knows what objects those NUL bytes you didn't make space for are smashing? And what happens when you read a data file with slightly different header spelling? Suddenly your hard-coded allocations sizes will be even more wrong than they are already.
Im new to c and am trying to understand pointers.
here I am opening a file and reading the lines given. Im trying to append these lines into an array and return it from the function. I dont seem to be appending or accessing the array correctly. output[count] = status; gives an error with mismatched char and char *.
Im essentially trying to get an array with a list of words given by a file where each element in the array is a word.
char *fileRead(char *command, char output[255]) {
int count = 0;
char input[255];
char *status;
FILE *file = fopen(command, "r");
if (file == NULL) {
printf("Cannot open file\n");
} else {
do {
status = fgets(input, sizeof(input), file);
if (status != NULL) {
printf("%s", status);
strtok(status, "\n");
// add values into output array
output[count] = status;
++count;
}
} while (status);
}
fclose(file);
return output;
}
I access fileRead via:
...
char commandArray[255];
char output[255];
int y = 0;
char *filename = "scriptin.txt";
strcpy(commandArray, fileRead(filename, output));
// read from array and pass into flag function
while (commandArray[y] != NULL) {
n = flagsfunction(flags, commandArray[y], sizeof(buf), flags.position, &desc, &parentrd, right, left, lconn);
y++;
...
Example of Read from file Line by line then storing nonblank lines into an array (array of pointer to char (as char*))
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//for it does not exist because strdup is not a standard function.
char *strdup(const char *str){
char *ret = malloc(strlen(str)+1);
if(ret)
strcpy(ret, str);
return ret;
}
//Read rows up to 255 rows
int fileRead(const char *filename, char *output[255]) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
perror("Cannot open file:");
return 0;
}
int count = 0;
char input[255];
while(count < 255 && fgets(input, sizeof(input), file)) {
char *line = strtok(input, "\n");
if(line)//When it is not a blank line
output[count++] = strdup(line);//Store replica
}
fclose(file);
return count;
}
int main(void){
char *output[255];//(`char *` x 255)
int number_of_read_line = fileRead("data.txt", output);
for(int i = 0; i < number_of_read_line; ++i){
printf("%s\n", output[i]);
free(output[i]);//Discard after being used
}
return 0;
}
I am using three files, my reverse.c, file_utils.h, and file_utils.c however after compiling successfully and executing I'm receiving a Segmentation Fault (core dumped). I'm unsure where the problem is. Thank you for any input!
Reverse.c File:
#include "file_utils.h"
#include <stdio.h>
#include <sys/stat.h>
//reverse function
//calls two parameters for a pointer to the input file and a pointer to the output file
//outputs the input file into the output in reverse
int reverse(char* inputFile, char* outputFile) {
char* buffer;
read_file(inputFile, &buffer);
struct stat st;
stat(inputFile, &st);
int size = st.st_size;
write_file(outputFile, buffer, size);
}
int main(int argc, char** argv[]) {
char* input;
char* output;
if(argv[1] != NULL) {
input = argv[1];
}
else {
printf("No input file detected.");
}
if(argv[2] != NULL) {
output = argv[2];
}
else {
printf("No output file detected.");
}
reverse(input, output);
}
file_utils.h Header:
#include <stdio.h>
void setup(int argc, char** argv);
int read_file( char* filename, char **buffer);
int write_file( char* filename, char *buffer, int size);
file_utils.c file:
#include "file_utils.h"
#include "stdlib.h"
//read_file function has two parameters which call a pointer to the input filenmae and
//a pointer to the pointer where the buffer will be stored
//returns the pointer to the newBuffer
int read_file( char* filename, char **buffer ) {
FILE *file;
file = fopen(filename, "r");
char* newBuffer = buffer;
int c;
size_t n = 0;
if(file == NULL) {
fprintf( stderr, "No file found. ");
return -1;
}
// length of file code found on stackoverflow.com/questions/4823177/reading-a-file
// given by user 'Justin'
fseek(file, 0, SEEK_END);
long f_size = ftell(file);
fseek(file, 0, SEEK_SET);
buffer = malloc(f_size);
if(newBuffer == NULL || newBuffer < 0) {
fprintf(stderr, "Memory allocation error. ");
}
while((c = fgetc(file)) != EOF) {
newBuffer[n++] = (char) c;
}
newBuffer[n] = '\0';
return *newBuffer;
}
//write_file function has three parameters which consist of a pointer to the output file,
//the actual value of the buffer pointer, and the size of the buffer
int write_file( char* filename, char *buffer, int size) {
fwrite(buffer, sizeof(char), size, filename);
}
my out put should be this
1) Hello...
2) Programming 1...
3) Students!
4) Welcome to File I/O!
I have done everything except i cannot figure out how to print the numbers for each line??
so far i got
#include <stido.h>
int main(int argc,char* argv[])
{
char string[200];
FILE* file = fopen("file2.txt","r");
while(fscanf(file, "%c", string) ==1)
{
printf("%c", *string);
}
fclose(file);
return 0;
}
int num = 1;
char line[200];
FILE* file = fopen("file2.txt","r");
while(fgets(line, 200, file))
{
printf("%d) %s", num, line);
num++;
}
To avoid limitation of line length like char string[200], simple detect the start of a line by checking if the precious char was a line-feed and then print the number. No need to be conservative on line count, so use a wide type.
#include <assert.h>
#include <stido.h>
int main(int argc,char* argv[]) {
int previous = '\n';
int ch;
unsigned long long line_count = 0;
FILE* file = fopen("file2.txt","r");
assert(file);
while((ch = fgetc(file)) != EOF) {
if (previous == '\n') {
printf("%llu) ", ++line_count);
}
fputc(ch, stdout);
previous = ch;
}
fclose(file);
return 0;
}
I have to read in a file such as
apple
grape
banana
And store it into a string, but fgets only reads up to the newline and stops, so its only reading in apple.
How do I get around this? Or how can I store the three words all as separate strings?
char* readFile(const char *fileName)
{
FILE *inFile;
inFile=fopen(fileName, "r");
char **stringInFile;
stringInFile = malloc(sizeof(char*)*50);
char *data = fgets(stringInFile,50,inFile);
printf("%s", data);
fclose(inFile);
return data;
}
This is all in C btw.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char** readFile(const char *fileName);
int main(int argc, char **argv){
char **data = readFile(argv[1]);
int i;
for(i=0; data[i] ; ++i){
puts(data[i]);
free(data[i]);
}
free(data);
return 0;
}
char** readFile(const char *fileName){
FILE *inFile;
inFile=fopen(fileName, "r");
char **stringInFile;
stringInFile = calloc(50, sizeof(char*));
char line[256];
int i = 0;
while(fgets(line, sizeof(line), inFile)){
char *p = strchr(line, '\n');
if(p)
*p = 0;
if(i < 50 - 1)
stringInFile[i++] = strdup(line);
}
fclose(inFile);
return stringInFile;
}
fgets() is only reading one Line by each call, and sets the file courser to the next line. If you want to read the fully file, you have to iterate it. To check if you are at the end, you can check for the EOF flag with feof().
Resulting in, for me working:
char* readFile(const char *fileName)
{
FILE *inFile;
inFile=fopen(fileName, "r");
char **stringInFile;
stringInFile = malloc(sizeof(char*)*50);
while(!feof(inFile))
{
printf("%s", fgets(stringInFile,50,inFile));
}
fclose(inFile);
return stringInFile;
}
And, you don't need the variable data - fgets() first parameter is a character Array, where is it automatical stored(for example Apple in your programm).