I am getting a segmentation fault for some reason, I wrote this program that calculates the days between two dates and wanted to get the "dd-mm-yyyy" to be represented as a string and "dd2-mm2-yyyy2"should also be represented as a string, i thought I could solve it this way, but i cam getting a segmentation fault, can someone help me? what am i doing wrong?
This seems incorrect. argv[1] is your "day" string, which is 1 or 2 characters long, and you're indexing characters 3 and 4.
char monstr[3];
monstr[0]= argv [1][3];
monstr[1]=argv [1][4];
monstr[2] = '\0';
This should probably be:
char monstr[3];
monstr[0]= argv [2][0];
monstr[1]=argv [2][1];
monstr[2] = '\0';
Same with some other strings.
But, that said, I'm basing this on how you seem to be parsing input. If you want your input to be dd-mm-yyyy, then you're not getting input right. Instead, you should do something like this:
int dd, mm, yyyy;
sscanf(argv[1], "%d-%d-%d", &dd, &mm, &yyyy);
And same with the other string. And in that case, the previous thing I corrected doesn't need to be corrected.
As a general piece of advice: the reason segmentation faults happen is because you're accessing memory that you aren't able to access. A common cause of this is going outside of array bounds, or using invalid pointers. In your case, it seems like one of those two, and it comes from misuse of argv.
Related
I'm trying to solve my homework.
The question is asking to implement the function count(FILE *fp) that takes as input a text file and returns the number of sentences in the file.
But the output is showing an error 'Segmentation fault (core dumped)'.
int count(FILE *fp)
{
int count=0;
char word[256];
while(fscanf(fp,"%s",word)!=EOF)
{
if(word[strlen(word)-1]=='.')
{
count+=1;
}
}
return count;
}
(If you're on Linux, compile your program with the -fsanitize=address flag. If your program runs into a segmentation fault, it will tell you in excruciating detail what went wrong).
If your file contains a "word" (sequence of characters which are not whitespace) longer than 256 characters (maybe the text is in German, or the text of Mary Poppins), fscanf will write that many characters into word, overflowing it. This can lead to segmentation faults.
You can prevent that by limiting the number of characters fscanf will try to write:
fscanf(fp,"%256s",word);
This may split a "word" into two or more parts, but only the last part with the dot will be counted (unless the word looks like "twohundred-and-fifty-five-characters.some-more").
Note that fscanf can return zero if no fields were stored, although this appears impossible when %s is used. In this case, you'll be applying strlen to uninitialized memory, which can lead to segmentation faults.
Also, if fscanf gives back an empty string (also appears impossible), strlen will return zero, and you'll try to read word[-1], that is, a buffer underrun. You should check the result of strlen before subtracting from it.
Here if strlen(word) returns a value grater than 256 (Meaning you have a sentence with more than 256 characters) you would get a segmentation fault.
You can find the solution in Bulletmagnet's answer
The program is getting input from a text file and then parsing them by space and then storing them in an array. I'm using the "<" in linux to read in the file.I needed to create a dynamically allocated array to store the words
if the input strings are "I am the cat in the hat"
then the array should look like:
index:
"I" "am" "the" "cat" "in" "the" "hat"
0 1 2 3 4 5 6
I am getting a segmentation fault and I can't figure out why I am getting the error? I need to Any help would be appreciated.
code:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main()
{
int wordCount = 1, i;
char ch,* wordsArray;
while((ch = getc(stdin)) != EOF)
{
if(ch == ' ') {++wordCount;}
}
wordsArray =(char*)malloc(wordCount * sizeof(char));
for(i = 0; i<wordCount; i++)
{
scanf("%s",&wordsArray[i]);
printf("%s\n", wordsArray[i])
}
return 0;
}
Edit: I have posted the actual code. I am no longer getting segmentation falls, but the words are not going in the array.
example output:
a.out<dict.txt
(null)
(null)
(null)
(null)
(null)
(null)
(null)
Briefly, you're asking scanf to scan strings into memory space that you've only allocated big enough for a few integers. Observe that your malloc call is given a number of ints to allocate and then you're assigning that to a char *. Those two things don't mix, and what's happening is you're scanning a bunch of bytes into your buffer that is too small, running off the end, and stomping on something else, then crashing. The compiler is letting you get away with this because both malloc and scanf are designed to work with various types (void*), so the compiler doesn't know to enforce the type consistency in this case.
If your goal is to save the word tokens from the input string into an array of words, you can do that but you need to allocate something quite different up front and manage it a bit differently.
But if your goal is simply to produce the output you want, there are actually simpler ways of doing it, like with using strtok or just looping through the input char by char and tracking where you hit spaces, etc.
What you're trying to accomplish is parsing standard input. Some functions are available to assist you, such as strtok() and strsep().
You will need an input buffer, which you can mallocate or use an array (I would use an array). As the functions parse the input string, you can fling off the words' addresses into a char pointer array. You could also build a linked list.
Finally, you must buffer input, which adds some delicious complexity to the operation. Still, it's nothing a good C programmer can't handle. Have fun.
I want to understand a number of things about the strings on C:
I could not understand why you can not change the string in a normal assignment. (But only through the functions of string.h), for example: I can't do d="aa" (d is a pointer of char or a array of char).
Can someone explain to me what's going on behind the scenes - the compiler gives to run such thing and you receive segmentation fault error.
Something else, I run a program in C that contains the following lines:
char c='a',*pc=&c;
printf("Enter a string:");
scanf("%s",pc);
printf("your first char is: %c",c);
printf("your string is: %s",pc);
If I put more than 2 letters (on scanf) I get segmentation fault error, why is this happening?
If I put two letters, the first letter printed right! And the string is printed with a lot of profits (incorrect)
If I put a letter, the letter is printed right! And the string is printed with a lot of profits and at the end something weird (a square with four numbers containing zeros and ones)
Can anyone explain what is happening behind?
Please note: I do not want the program to work, I did not ask the question to get suggestions for another program, I just want to understand what happens behind the scenes in these situations.
Strings almost do not exist in C (except as C string literals like "abc" in some C source file).
In fact, strings are mostly a convention: a C string is an array of char whose last element is the zero char '\0'.
So declaring
const char s[] = "abc";
is exactly the same as
const char s[] = {'a','b','c','\0'};
in particular, sizeof(s) is 4 (3+1) in both cases (and so is sizeof("abc")).
The standard C library contains a lot of functions (such as strlen(3) or strncpy(3)...) which obey and/or presuppose the convention that strings are zero-terminated arrays of char-s.
Better code would be:
char buf[16]="a",*pc= buf;
printf("Enter a string:"); fflush(NULL);
scanf("%15s",pc);
printf("your first char is: %c",buf[0]);
printf("your string is: %s",pc);
Some comments: be afraid of buffer overflow. When reading a string, always give a bound to the read string, or else use a function like getline(3) which dynamically allocates the string in the heap. Beware of memory leaks (use a tool like valgrind ...)
When computing a string, be also aware of the maximum size. See snprintf(3) (avoid sprintf).
Often, you adopt the convention that a string is returned and dynamically allocated in the heap. You may want to use strdup(3) or asprintf(3) if your system provides it. But you should adopt the convention that the calling function (or something else, but well defined in your head) is free(3)-ing the string.
Your program can be semantically wrong and by bad luck happening to sometimes work. Read carefully about undefined behavior. Avoid it absolutely (your points 1,2,3 are probable UB). Sadly, an UB may happen to sometimes "work".
To explain some actual undefined behavior, you have to take into account your particular implementation: the compiler, the flags -notably optimization flags- passed to the compiler, the operating system, the kernel, the processor, the phase of the moon, etc etc... Undefined behavior is often non reproducible (e.g. because of ASLR etc...), read about heisenbugs. To explain the behavior of points 1,2,3 you need to dive into implementation details; look into the assembler code (gcc -S -fverbose-asm) produced by the compiler.
I suggest you to compile your code with all warnings and debugging info (e.g. using gcc -Wall -g with GCC ...), to improve the code till you got no warning, and to learn how to use the debugger (e.g. gdb) to run your code step by step.
If I put more than 2 letters (on scanf) I get segmentation fault error, why is this happening?
Because memory is allocated for only one byte.
See char c and assigned with "a". Which is equal to 'a' and '\0' is written in one byte memory location.
If scanf() uses this memory for reading more than one byte, then this is simply undefined behavior.
char c="a"; is a wrong declaration in c language since even a single character is enclosed within a pair of double quotes("") will treated as string in C because it is treated as "a\0" since all strings ends with a '\0' null character.
char c="a"; is wrong where as char c='c'; is correct.
Also note that the memory allocated for char is only 1byte, so it can hold only one character, memory allocation details for datatypes are described bellow
I am quite new to C and any examples I have found of my problem didn't seem to work, or I completely misunderstood what that solution was. I have a large file with data that looks like:
LYS 24L HB2 45.212 39.585 124.457 SC0 0.145 -0.795 0.585 0.157
on each line. I have tokenized the data already using strtok. What I need is from the second field, I wish to have the 24 stored as an integer for comparison, and the L to be stored as a char for comparison as well.
I tried using
sscanf(token[1], "%d%s", number, letter);
but I keep getting Segmentation fault error. Also upon further experimenting with sscanf i tried simply to print out "LYS" (in attempt to further understand my problem) however my program would only print L using the following command:
sscanf(token[0], "%c", &stemp);
letter = stemp;
printf("%c \n", letter);
However if change %c ---> %s (hoping to obtain the whole string) then I obtain the Segmentation fault error once again ... Is there something I do not understand about the sscanf command? Why can i not read in a full string?? Thank you in advance for your time and help!!
Paul
I suspect the issue is actually that number and letter are of type int and char, respectively. scanf() needs addresses of memory locations in which to store the values, not the variables themselves; i.e.,
int number;
char letter[2];
sscanf(token[1], "%d%s", &number, letter);
I've made letter into an array of two characters, and am passing the address of the array; that matches the %s scan conversion that you've used.
The program should be able to make an array of numbers from a text file which reads like this
The data is given as this
123 2132 1100909 3213 89890
my code for it is
char a;
char d[100];
char array[100];
a=fgetc(fp) // where fp is a file pointer
if (a=='')
{
d[count1]='/0';
strcpy(&array[count],d);
count=count+1;
memset(d,'\0',100)
count1=0;
}
else
{
d[count1]=a;
count1=count1+1;
}
a=fgetc(fp);
i am getting segmentation fault now . want to store each number in the array so that i can do sorting on it
Your (first) problem is here:
d[count1]='/0';
strcpy(&array[count],d);
You have written '/0', which isn't what you think it is. Assuming you meant '\0' (a null char literal), then you appear to be trying to manually terminate the string d before calling strcpy(). The problem is that what actually gets written to d is not a null byte, and so d is not null-terminated, and then strcpy() goes off and starts reading random memory after it, and copying that memory into array, until either the reading or the writing ends up outside of memory you're allowed to access, and you get a segmentation fault.
You also have some confusion about that array is. It's declared as an array of 100 chars, but you're treating it like it's an array of strings. Perhaps you meant to declare it as char *array[100] ?
Hmm...as a first approximation, to read a single number, consider using fscanf("%d", &number);. To store the numbers you read, you'll probably want to create an array of numbers (e.g., int numbers[100];). To read more than one number, use a loop to read the numbers into the array.
Sidenote: fscanf isn't particularly forgiving of errors in the input (among other things) so for production code, you probably want to read a string, and parse numbers out of that, but for now, it looks like you probably just need to get something that works for correct input, not worry about handling incorrect input gracefully.
Is this actually how the code is written?
In d[count1]='/0'; I think you mean d[count1]='\0'; (already mentioned by Daniel Pryden).
There is also a semicolon missing at the end of memset(d,'\0',100)