Receiving Segmentation Fault in basic reverse text C code - c

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);
}

Related

Segmentation fault in C while iterating through array

I am trying to mimic a basic encryption algorithm. I try to read the encrypted data file and look for each corresponding value in a JRB tree (simple key-value pair in my case) which is basically filled from the ".key" file and then write it to another file.
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "fields.h"
#include <cJSON.h>
#include "jrb.h"
void decrypt();
int main(int argc, char **argv)
{
decrypt();
return 0;
}
void decrypt()
{
IS is_input;
FILE *fp;
int i, j;
char *buffer = 0;
char *str = 0;
long length;
FILE *f = fopen ("data/.key", "rb");
cJSON *json;
JRB b, tmp;
b = make_jrb();
tmp = make_jrb();
is_input = new_inputstruct("data/encrypted");
if (is_input == NULL) {
perror("Error: ");
exit(1);
}
fp = fopen("data/decrypted.txt", "w+");
if (fp < 0) { perror("Error: "); exit(1); }
if (f)
{
fseek (f, 0, SEEK_END);
length = ftell (f);
fseek (f, 0, SEEK_SET);
buffer = malloc (length);
if (buffer)
{
fread (buffer, 1, length, f);
}
fclose (f);
}
if (buffer)
{
json = cJSON_Parse(buffer);
cJSON *current_element = NULL;
char *current_key = NULL;
cJSON_ArrayForEach(current_element, json)
{
current_key = current_element->string;
if (current_key != NULL)
{
(void) jrb_insert_str(b, strdup(current_element->valuestring), new_jval_v(current_key));
}
}
while(get_line(is_input) >= 0) {
for (i = 0; i < is_input->NF; i++) {
str = is_input->fields[i];
tmp = jrb_find_str(b, "10001011"); // This works but when I use "str" here instead of "10001011", I get a segmentation fault.
// tmp = jrb_find_str(b, str);
fprintf(fp, "%s ", tmp->val.s);
}
}
}
jettison_inputstruct(is_input);
fclose(fp);
return;
}
The .key file is like this:
{
"hi": "0",
"merhaba": "10",
"hallo": "11"
}
After running the program with printf I get a Segmentation fault after printing it is data like this:
0 10 11Segmentation fault (core dumped)
But if I try to use fprintf to write it into another file I directly get the Segmentation fault error.
I tried to debug and I see that the tmp value is null but how can it be null?
About JRB: http://web.eecs.utk.edu/~jplank/plank/classes/cs360/360/notes/JRB/index.html
Input struct:
const char *name; /* File name */
FILE *f; /* File descriptor */
int line; /* Line number */
char text1[MAXLEN]; /* The line */
char text2[MAXLEN]; /* Working -- contains fields */
int NF; /* Number of fields */
char *fields[MAXFIELDS]; /* Pointers to fields */
int file; /* 1 for file, 0 for popen */

how to turn my iterative for loop into recursive code without getting a stack error

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
int read_file(char* filename, char **buffer) {
FILE* file1;
file1 = fopen(filename, "r");
//gets the size of the file
struct stat st;
stat(filename, &st);
int size = st.st_size;
*buffer = malloc(size);
fread(*buffer, size, 1, file1);
fclose(file1);
return size;
}
void write_file(char* filename, char*buffer, int size) {
FILE* file2 = fopen(filename, "w"); int k;
for (k = size - 1; k >= 0; k--) {
fwrite(buffer + k, 1, 1, file2);
}
fclose(file2);
}
int main(int argc, char *argv[]) {
char* buffer;
char* filename1;
char* filename2;
int filesize;
//create an array and for loop to call the fread more than once
filename1 = "Bible.txt";
filename2 = "reverse.txt";
filesize = read_file(filename1, &buffer);
write_file(filename2, buffer, filesize);
free(buffer);
return 0;
}
Some info: I was able to successfully reverse a text file of a textbook, however I used iterative. It is also supposed to be written recursively but I keep getting stack errors. Any ideas are appreciated on what I can try.

Error using fprintf and fscanf

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.

adding char into an array and returning

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;
}

C programming, reading from file error?

My code is not putting the text file data into line on the second pass of the while loop, and any subsequent pass. I'm sure it's a silly error but I cannot find it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *fr;
char *line,*word,*vali;
ssize_t read;
int i=0,sum=0,len =0,flag=0;
const char delim[2]=" ";
int main(int argc, char* argv[])
{
line = (char *)malloc(sizeof(&len));
word = (char *)malloc(sizeof(&len));
vali = (char *)malloc(sizeof(&len));
fr = fopen(argv[1], "r");
if(fr==NULL)
{
exit(EXIT_FAILURE);
}
while ((read = getline(&line, &len, fr)) != -1)
{
printf("line is %s\n", line );
fscanf(fr,"%s%*[^\n]",word);
printf("%s ", word);
vali=strtok(line, delim);
while(vali != NULL)
{
sum=sum+atoi(vali);
vali = strtok(NULL, delim);
}
printf("%d\n", sum);
sum=0;
vali=" ";
len = strlen(line);
}
fclose(fr);
if (line)
free(line);
return 0;
}
If len is some integral type containing the desired length of the first line, then:
&len
Has type pointer-to-integer, and
sizeof(&len)
Returns the size of a pointer (8 bytes on most 64 bit systems) and
malloc(sizeof(&len))
Allocates only 8 bytes of memory (or whatever pointer size is on your system).
This is probably at least part of the issue.

Resources