Getting segmentation fault when using fgets and strtok - c

I am trying to read a txt file and then split the numbers and store them in a matrix. However when I try to use strtok I'm getting segmentation fault. Can somebody help me with this pleaseļ¼
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
void parse(char*file1)
{
FILE *fp;
char str[60];
char str1[60];
fp = fopen(file1, "r");
int row;
int col;
fgets(str, 60, fp);
row=atof(str);
fgets(str, 60, fp);
col=atof(str);
double *matrix;
matrix = (double *)malloc(sizeof(double)*row*col);
int j;
int i;
for(i=0; i < row; i++) {
for(j=0; j < col; j++) {
matrix[i*col +j] = 1;
}
}
for(i=0; i < row; i++) {
for(j=0; j < col; j++) {
printf("%f ",matrix[i*col +j]);
}
printf("\n");
}
printf("**************************");
double dtoken;
while (!feof(fp))
{
if (fgets(str, 60, fp)==NULL)
{
break;
}
else
{
char*token;
token = strtok(str, " ");
while (token!=NULL)
{
printf("%s ",token);
token=strtok(NULL, " ");
}
}
printf("\n");
}
fclose(fp);
}
int main(int argc, char*argv[])
{
int i;
char*file1;
char*file2;
if (argc==1) //print error when no txt file is entered
{
printf("Invalid text file.\n");
exit(1);
}
else if (argc==2)
{
file1=argv[1];
file2=argv[1];
}
else if (argc==3)
{
file1=argv[1];
file2=argv[2];
}
else
{
exit(1);//more than 3 files, invalid
}
//
parse(file1);
}
I tried copying str to str1 and use strtok on str1 and that did not work either.

In the function parse() change str1[60]='\0'; to str1[59]='\0';
As you have allocated memory only for 60 characters and trying to access the 61st character.
In arrays you need to count from 0 to 59 and not from 1 to 60 if the size of allocated array is 60.
EDIT:
Check for the return value of fopen
After fp = fopen(file1, "r"); add below code
if (fp == NULL ) {
printf("Error: Unable to open file\n");
return ;
}

You are causing undefined behavior by accessing str1 out of bounds. You can replace the lines:
strncpy(str1,str,60);
str1[60]='\0';
by
strcpy(str1,str);
That will work fine since both str and str1 are arrays with 60 elements.

Related

Selectively reading string part of a file using C

I have a .txt file with strings each line and a number assigned to each string and a - in between the string and the number.
Now I want to read only the string part not the number or the - in between, store them in an array and write only the strings in another file.
I used the following approach:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
struct String {
long long int num;
char name[50];
char C;
} S[MAX], temp;
void file_write(int n, struct String S[]) {
FILE *pp;
pp = fopen("std3.txt", "a"); //second file where I want to write only string part.
for (int i = 0; i < n; i++) {
fprintf(pp, "%s", S[i].name); //storing the strings in another file
fputs("\n", pp);
}
fclose(pp);
}
int main() {
int n;
FILE *fp;
fp = fopen("str.txt", "r");
printf("Enter the number of strings : ");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
fscanf(fp, " %[^\n]", S[i].name);
fscanf(fp, "%lld", &S[i].num);
fscanf(fp, "%c", &S[i].C);
}
file_write(n, S);
fclose(fp);
return 0;
}
But I'm getting an undesirable output:
Here is a simple solution using fscanf() and the * assignment suppression option:
#include <stdio.h>
int main() {
int n = 0;
FILE *fp = fopen("str.txt", "r");
// second file where I want to write only string part.
FILE *pp = fopen("std3.txt", "a");
if (fp == NULL || pp == NULL) {
fprintf(stderr, "cannot open files\n");
return 1;
}
printf("Enter the number of strings: ");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
char name[50];
int c;
if (fscanf(fp, "%*d - %49[^\n]", name) == 1) {
fprintf(pp, "%s\n", name);
/* flush any extra characters and the newline if present */
while ((c = getc(fp)) != EOF && c != '\n')
continue;
} else {
break;
}
}
fclose(fp);
fclose(pp);
return 0;
}
Scanf (and its variations) is a very powerful function... I think the following line is what you want.
for(int i=0;i<n;i++)
{
fscanf(fp, "%*[^A-Z]%[^\n]", S[i].name);
}
A brief description of what it does is: It discards any character that is not a capital letter then reads everything from the first capital letter until the end of line.
If the names are allowed to start with lowercase, you can change it to:
fscanf(fp, "%*[^A-Za-z]%[^\n]", S[i].name);

Thread 1: EXC_BAD_ACCESS (code=1, address=0x68 [duplicate]

I am new to C programming and I am getting a THREAD 1: EXC_BAD_ACCESS(code = 1, address 0x68)
when I run my program. The purpose of my code is to read from a txt file that contains positive and negative numbers and do something with it.
#include <stdio.h>
int main (int argc, const char * argv[]) {
FILE *file = fopen("data.txt", "r");
int array[100];
int i = 0;
int num;
while( fscanf(file, "%d" , &num) == 1) { // I RECEIVE THE ERROR HERE
array[i] = num;
printf("%d", array[i]);
i++;
}
fclose(file);
for(int j = 0; j < sizeof(array); j++){
printf("%d", array[j]);
}
}
After
FILE *file = fopen("data.txt", "r");
Say
if(file == 0) {
perror("fopen");
exit(1);
}
Just a guess, the rest of the code looks ok, so likely this is the problem.
Also worth noting that you might have more than 100 numbers in your file, in which case you will blow past the size of your array. Try replacing the while loop with this code:
for (int i = 0; i < 100 && ( fscanf(file, "%d" , &num) == 1); ++i)
{
array[i] = num;
printf("%d", array[i]);
}
Do you have the file "data.txt" created and local?
touch data.txt
echo 111 222 333 444 555 > data.txt
Check that your file open succeeded.
Here is a working version,
#include <stdio.h>
#include <stdlib.h> //for exit
int main (int argc, const char * argv[])
{
FILE *fh; //reminder that you have a file handle, not a file name
if( ! (fh= fopen("data.txt", "r") ) )
{
printf("open %s failed\n", "data.txt"); exit(1);
}
int array[100];
int idx = 0; //never use 'i', too hard to find
int num;
while( fscanf(fh, "%d" , &num) == 1) { // I RECEIVE THE ERROR HERE
array[idx] = num;
printf("%d,", array[idx]);
idx++;
}
printf("\n");
fclose(fh);
//you only have idx numbers (0..idx-1)
int jdx;
for(jdx = 0; jdx<idx; jdx++)
{
printf("%d,", array[jdx]);
}
printf("\n");
}

Read integers from text file into matrix in c - Access violation

trying to read in from a text file with 10 lines of 10 numbers separated by spaces. I want to directly save each number into a space in the matrix numList.
Really not sure what the problem is with my code, I think it might be because i'm not initializing the matrix correctly or something. Any help appreciated
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
FILE* fpointer = fopen("numbers.txt", "r");
if (fpointer == NULL) {
printf("No file found");
return 1;
}
// INITIALISE MATRIX
char* numList[10][10];
char buffer[300];
// COPY NUMBERS INTO MATRIX
int i = 0;
while (fgets(buffer, 300, fpointer)) {
int j = 0;
char* p = strtok(buffer, " ");
while ((p != NULL)&&(j<10)) {
printf(" %s ",p);
strcpy(numList[i][j],p);
p = strtok(NULL, " ");
j++;
}
printf("\n");
i++;
}
printf("\n\n");
//Print Final Matrix
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
printf("%s ", numList[i][j]);
}
printf("\n");
}
fclose(fpointer);
return 0;
}
Problem is occurring on the strcpy(numList[i][j],p) function but i'm not sure why.
Output: Exception thrown at 0x7C15EE87 (ucrtbased.dll) in asd.exe: 0xC0000005: Access violation writing location 0xCCCCCCCC.
No memory is allocated for numList[i][j]
You can use strdup instead of strcpy
while (fgets(buffer, 300, fpointer)) {
int j = 0;
char* p = strtok(buffer, " ");
while ((p != NULL)&&(j<10)) {
printf(" %s ",p);
numList[i][j] = strdup(p);
p = strtok(NULL, " ");
j++;
}
printf("\n");
i++;
}

fscanf not reading from a file containing asterisk characters

I tried to read a file containing an empty box of '*', the error message doesn't get printed, so the file is opened, but the scan doesn't work. I tried to print the count variable, and the value of count is 0. I don't really know where the fault is. Please help... Thanks
the file content that I want to read
int openmap(int file_no){
char filename[32];
char mapp[100][100];
int number;
int count;
int x[100];
int nomor = 1;
for(int i = 1; i <= file_no; i++){
sprintf(filename, "map%d.txt", i);
FILE *test = fopen(filename,"r");
if(test)
{
printf("%2d. Map %d\n", nomor, i);
x[nomor-1] = i;
nomor++;
fclose(test);
}else if(!test && i > file_no){
printf("No map available!");
return 1;
}
}
do{
printf("[0 to cancel] [1 - %d]>> ", nomor-1);
scanf("%d", &number);
}while(number < 0 || number > file_no);
if(number > 0){
sprintf(filename,"map%d.txt", x[number-1]);
printf("%s", filename);
FILE *open = fopen(filename, "r");
if(!open){
printf("error");
}
while(!feof){
fscanf(open, "%[^\n]\n", mapp[count]);
count++;
}
fclose(open);
for(int i = 0; i < count ; i++){
printf("%s\n", mapp[i]);
}
}
}
I created a small test program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main () {
char mapp[100][100];
int i, count = 0;
char filename[32];
sprintf(filename, "test.txt");
FILE *open = fopen(filename, "r");
if(!open){
printf("error");
}
while(!feof(open)){
fscanf(open, "%[^\n]\n", mapp[count]);
count++;
}
fclose(open);
for(i = 0; i < count ; i++){
printf("%s\n", mapp[i]);
}
}
as far as i can see the only issue you have regarding the relevant section is your while loop condition, you should use: while(!feof(open)) - i tested my solution and it works so it seems that this is the only issue in your solution

Error when trying to read in numbers from txt file in C

I am new to C programming and I am getting a THREAD 1: EXC_BAD_ACCESS(code = 1, address 0x68)
when I run my program. The purpose of my code is to read from a txt file that contains positive and negative numbers and do something with it.
#include <stdio.h>
int main (int argc, const char * argv[]) {
FILE *file = fopen("data.txt", "r");
int array[100];
int i = 0;
int num;
while( fscanf(file, "%d" , &num) == 1) { // I RECEIVE THE ERROR HERE
array[i] = num;
printf("%d", array[i]);
i++;
}
fclose(file);
for(int j = 0; j < sizeof(array); j++){
printf("%d", array[j]);
}
}
After
FILE *file = fopen("data.txt", "r");
Say
if(file == 0) {
perror("fopen");
exit(1);
}
Just a guess, the rest of the code looks ok, so likely this is the problem.
Also worth noting that you might have more than 100 numbers in your file, in which case you will blow past the size of your array. Try replacing the while loop with this code:
for (int i = 0; i < 100 && ( fscanf(file, "%d" , &num) == 1); ++i)
{
array[i] = num;
printf("%d", array[i]);
}
Do you have the file "data.txt" created and local?
touch data.txt
echo 111 222 333 444 555 > data.txt
Check that your file open succeeded.
Here is a working version,
#include <stdio.h>
#include <stdlib.h> //for exit
int main (int argc, const char * argv[])
{
FILE *fh; //reminder that you have a file handle, not a file name
if( ! (fh= fopen("data.txt", "r") ) )
{
printf("open %s failed\n", "data.txt"); exit(1);
}
int array[100];
int idx = 0; //never use 'i', too hard to find
int num;
while( fscanf(fh, "%d" , &num) == 1) { // I RECEIVE THE ERROR HERE
array[idx] = num;
printf("%d,", array[idx]);
idx++;
}
printf("\n");
fclose(fh);
//you only have idx numbers (0..idx-1)
int jdx;
for(jdx = 0; jdx<idx; jdx++)
{
printf("%d,", array[jdx]);
}
printf("\n");
}

Resources