segmentation fault (core dumped) error in C program - c

I tried to compile and run the following program to reverse a string using the gcc compiler for linux but it shows the error : segmentation fault (core dumped).I even tried to debug using gdb but it didn't help. The program given below firstly inputs t which is the number of test cases.I tested the program with 3 test cases but after taking the 2nd input from user, the compiler shows error.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* strrev(char*);
int main(int argc, char *argv[])
{
int t,i=0,temp=0;
char *str[10],*rev[10];
scanf("%d",&t); //input the number of test cases
while(i<t)
{
scanf("%s",str[i]);
i++;
}
while(temp<t) //reverse the string and display it
{
rev[temp]=strrev(str[temp]);
printf("%s \n",rev[temp]);
temp++;
}
return 0;
getchar();
}
Function to reverse the string:
char *strrev(char *str)
{
int i = strlen(str)-1,j=0;
char ch;
while(i>j)
{
ch = str[i];
str[i]= str[j];
str[j] = ch;
i--;
j++;
}
return str;
}

You are getting segmentation fault because you haven't allocated space for elements of str.
You need to allocate memory first in main function.
scanf("%d",&t); //input the number of test cases
if(t <= 10)
for(size_t i = 0; i < t; i++)
str[i] = malloc(50); // Assuming string is no more than 50characters.
else
exit(0);
Beside this there are many flaws in your code. Here is the code after fixing them
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void strrev(char*); // Change return type to void
int main(void)
{
int t,i=0,temp=0, ch;
char *str[10];
scanf("%d",&t); //input the number of test cases
while((ch = getchar()) != EOF && ch != '\n'); // To consume newline character after scanf
// Allocate memory for str elements
if(t <= 10)
for(size_t i = 0; i < t; i++)
str[i] = malloc(50); // Assuming string is no more than 50characters.
else
exit(0);
i = 0;
while(i < t)
{
fgets(str[i],50,stdin); // Use fgets instead of scanf to read string
i++;
}
while(temp<t) //reverse the string and display it
{
// Since you are reversing string by flipping the characters the same
// string just pass pointer to it. str[temp] will be updated in function.
strrev(str[temp]);
printf("Reverse is %s \n", str[temp]);
temp++;
}
return 0;
}
void strrev(char *str)
{
size_t i = strlen(str)-1,j=0;
char ch;
while(i>j)
{
ch = str[i];
str[i]= str[j];
str[j] = ch;
i--;
j++;
}
//printf("Reverse is %s \n", str);
}

you have missed to allocate memory before reading char* value, so you can do this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* strrev(char*);
int main(int argc, char *argv[])
{
int t,i=0,temp=0;
char *str[10],*rev[10];
scanf("%d",&t); //input the number of test cases
while(i<t)
{
str[i] = (char*)malloc(100); // just allocate memory
scanf("%s", str[i]);
i++;
}
while(temp<t) //reverse the string and display it
{
rev[temp]=strrev(str[temp]);
printf("%s \n",rev[temp]);
temp++;
}
return 0;
getchar();
}

char *str[10],*rev[10];
You did not assign storage to hold string values yet for those pointers.
char * str; /* this is a string pointer */
char * str = malloc(15); /* this creates storage for a string */
char str[10]; /* this creates a static char array, also is a string */

I also had the same issue. I just fixed it by correcting the indices of the matrix.

Related

reading and saving known number of lines of unknown lengths of strings

I want to receive the number of lines of input from the user then read and save the lines of unknown lengths in an array.
I know that the way I am saving the lines is wrong but I don't know how to correct it.
int nos; // number of strings
scanf_s("%d", &nos);
char** strs = malloc(nos * sizeof(char*)); // array of strings
for (int i = 0; i < nos; i++) // receiving strings
{
scanf_s("%s", (strs+i));
}
You're close, but you're forgetting to allocate memory for the string. If you're working with POSIX-compliant systems (i.e. pretty much everything except Windows) then use the %ms scanf() format specifier to allocate the buffer for the string as you're reading it (note that this stops after whitespace):
scanf("%ms", &strs[i]);
For Windows, implement a gets()-like function:
#include <stdlib.h>
#include <stdio.h>
int msgets(char **str)
{
int ch = 0;
size_t len = 0;
while(ch != '\n')
{
len++;
*str = realloc(*str, len);
ch = getchar();
(*str)[len-1] = ch;
}
(*str)[--len] = 0;
return len;
}
Here's how to use it in replacement of the scanf() line:
msgets(&strs[i]);
Other than that, your code looks fine.
Here's an almost complete example with my code included:
#include <stdlib.h>
#include <stdio.h>
int msgets(char **str)
{
int ch = 0;
size_t len = 0;
while(ch != '\n')
{
len++;
*str = realloc(*str, len);
ch = getchar();
(*str)[len-1] = ch;
}
(*str)[--len] = 0;
return len;
}
int main(void)
{
int nos; // number of strings
scanf("%d ", &nos);
char** strs = malloc(nos * sizeof(char*)); // array of strings
for (int i = 0; i < nos; i++) // receiving strings
{
msgets(&strs[i]);
}
/* Do something with strs[] here */
return 0;
}
if you read carefully this answerHow can I read an input string of unknown length? , and modify your code it should be something like this.
I also add a print for loop to see the results of this code
#include <stdio.h>
#include <stdlib.h>
char *inputString(FILE* fp, size_t size){
char *str=NULL;
int ch;
size_t len = 0;
str = realloc(str, sizeof(char)*size);
if(!str){
printf("[DEBUG]\n");
return str;
}
while(EOF!=(ch=fgetc(fp)) && ch != '\n'){
str[len++]=ch;
if(len==size){
str = realloc(str, sizeof(char)*(size+=16));
if(!str)return str;
}
}
str[len++]='\0';
return realloc(str, sizeof(char)*len);
}
void empty_stdin (void) /* simple helper-function to empty stdin */
{
char c;
while ((c = getchar()) != '\n' && c != EOF);
return;
}
int main(void){
int nos,i; /*number of strings*/
scanf("%d", &nos);
empty_stdin();
char ** strs = malloc(nos * sizeof(char*)); /*array of strings*/
for (i = 0; i < nos; i++) {/*receiving strings*/
*(strs+i) = inputString(stdin,1);
}
for(i=0;i<nos;i++){
printf("%s\n",*(strs+i));
}
return 0;
}
input:
3
123456789
foo
hello world
output:
123456789
foo
hello world

segmentation fault in c about using malloc, and char array pointer

im trying to make a program which reads what we wrote without concerning the memory, and print out what we wrote!
but it goes to segmentation fault (core dump)
#include <stdio.h>
#include <string.h>
int isdigit(char c);
int main()
{
char *input
int length;
printf("Number or Letter\n");
gets(input);
input = (char*)malloc(sizeof(char)*strlen(input));
printf(input[0]);
return 0;
}
To read in an arbitrary long input string, you must use some kind of memory re-allocation when the input string grows beyond the already allocated memory. For instance you could use realloc like this:
#include <stdio.h>
#include <stdlib.h>
#define INCREASE 32
int main(void) {
int c;
int allocated = INCREASE;
int used = 1;
char* in = malloc(allocated*sizeof(char));
if (!in) exit(1);
*in = '\0';
while((c = fgetc(stdin)) != EOF && c != '\n')
{
if (used > (allocated-1))
{
// printf("Realloc\n");
allocated += INCREASE;
char* t = realloc(in, allocated);
if (t)
{
in = t;
}
else
{
free(in);
exit(1);
}
}
in[used-1] = c;
in[used] = '\0';
++used;
}
printf("%s\n", in);
free(in);
return 0;
}

Need to write a C Program to remove repeated characters adjacent to each other

I need to remove only the repeated characters that are adjacent to each other.
Example: if the input is "heeellooo wooorllldd", the output should be "helo world". The output I am currently getting is "helo wrd".
This is the code i have.
#include <stdio.h>
#include <string.h>
main()
{
char str[]="heeello wooorld";
redundant(str);
}
void redundant(char *str)
{
int check=0;
int i,j;
char ch;
while(str[check])
{
ch = str[check];
i = j = check + 1;
while(str[i])
{
if(str[i] != ch)
{
str[j] = str[i];
j++;
}
i++;
}
str[j]='\0';
check++;
}
printf("String after removing duplicates : %s\n",str);
}
I was looking for a minimalistic solution. Just for fun.
void redundant(char *str) {
int lastch = -1; /* last read character */
char* inpp = str; /* pointer to input location */
char* outp = str; /* pointer to output location */
while (*inpp != '\0') {
if (*inpp != lastch) {
*outp++ = lastch = *inpp;
}
inpp++;
}
*outp = '\0';
printf("String after removing duplicates : %s\n", str);
}
Whats happening is that your in code a character is taken and then the entire string is checked if the same character is present again .If it is present it is deleted .Therefore your program has only one copy of each character instead of deleting adjacent same characters.
Try this code instead :
#include<stdio.h>
#include<string.h>
#include <stdio.h>
#include <conio.h>
void redundant(char *);
main()
{
clrscr();
char str[]="heeello wooorld";
redundant(str);
getch();
}
void redundant(char *str)
{
int check=0;
int i,j;
char ch;
while(str[check]) {
j=i=check;
ch= str[check+1];
if(str[check] == ch)
{
i++;
check--;
}
while(str[i]) {
str[j] = str[i];
j++;
i++;
}
str[j]='\0';
check++;
}
printf("String after removing duplicates : %s\n",str);
}
In my code i check if the adjacent character is same or not.If yes I copy the entire string from the next to next position instead.
You could have shortened code by using strcat function as shown :
void redundant(char *str)
{
int check=0;
while(str[check]) {
if(str[check] == str[check+1])
{
str[check+1]='\0';
strcat(str,str+check+2);
check--;
}
check++;
}

Getting a segmentation fault in my code

My code is giving me a segmentation fault. I'm 99% sure the fault is stemming from my lousy code construction.
#include <stdio.h>
#include <assert.h>
#include <string.h>
int decToBit(unsigned int I, char *str){
str = "";
int currentVal = I;
do{
if(I%2 == 0)
strcat(str,"0");
else
strcat(str,"1");
} while(currentVal > 0);
return(0);
}
You need to make sure that there is enough space in str to add the extra characters:
char myStr[200];
myStr[0] = '\0'; // make sure you start with a "zero length" string.
strcpy(myStr, str);
and then use myStr where you were using str.
As it is, the statement
str="";
points str to a const char* - that is a string you can read but not write.
Incidentally the call signature for main is
int main(int argc, char *argv[])
in other words, you need a pointer to a pointer to char. If I am not mistaken, you would like to do the following (a bit of mind reading here):
Every odd argument gets a 1 added; every even argument gets a 0 added.
If my mind reading trick worked, then you might want to try this:
#include <stdio.h>
#include <string.h>
int main(int argc, char * argv[]) {
char temp[200];
temp[0] = '\0';
int ii;
for(ii = 0; ii < argc; ii++) {
strncpy(temp, argv[ii], 200); // safe copy
if(ii%2==0) {
strcat(temp, "0");
}
else {
strcat(temp, "1");
}
printf("%s\n", temp);
}
}
edit just realized you edited the question and now your purpose is much clearer.
Modified your function a bit:
int decToBit(unsigned int I, char *str){
str[0] = '\0';
char *digit;
do
{
digit = "1";
if ( I%2 == 0) digit = "0";
strcat(str, digit);
I>>=1;
} while (I != 0);
return(0);
}
It seems to work...
In do-while loop you should increment the value of currentVal. Otherwise it will be an infinity loop and you will end up with Segmentation fault.
Initialize str[0] properly.
Divide I by 2 each loop.
But then the string will be in a little endian order. Doubt that was intended?
int decToBit(unsigned int I, char *str) {
str[0] = '\0';
do {
if (I%2 == 0)
strcat(str,"0");
else
strcat(str,"1");
I /= 2;
} while(I > 0);
return(0);
}
// call example
char buf[sizeof(unsigned)*CHAR_BIT + 1];
decToBit(1234567u, buf);
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
char *decToBit(unsigned int I, char *str){
int bit_size = CHAR_BIT * sizeof(I);
str += bit_size;
*str = 0;
do{
*--str = "01"[I & 1];
}while(I>>=1);
return str;
}
int main(){
char bits[33];
printf("%s\n", decToBit(0, bits));
printf("%s\n", decToBit(-1, bits));
printf("%s\n", decToBit(5, bits));
return 0;
}

Returning position of any character in the text

The program is designed to return the position of the character in the table s2, in the text of Table S1. In case of failure it will a return -1.
#include <stdio.h>
#include <stdlib.h>
#define RANGE 10
int any(char [], char []);
int main()
{
char s1[RANGE];
char s2[RANGE];
int i,j;
while( (s1[i]=getchar()) != EOF);
while( (s2[j]=getchar()) != EOF);
printf("%d", any(s1, s2));
}
int any(char s1[], char s2[])
{
int i,j;
for(i=0;s1[i]!='\0';i++)
for(j=0;s2[j]!='\0';j++)
{
// for debug
printf("\n%s", s1[i]);
printf("\n%s", s2[j]);
//
if(s1[i]==s2[j])
return i;
}
return -1;
}
It seems to me that the problem occurs when comparing the characters in the tables.
In this case, programme should return -1:
The code has the following problems:
(1) Variables i and j are uninitialized in the code, potentially causing a crash:
int i,j;
while( (s1[i]=getchar()) != EOF);
while( (s2[j]=getchar()) != EOF);
(2) The code also needs to increment the values of i and j as input is being read. Failing to do so will cause all input to be written to s1[0] / s2[0]:
while( (s1[i]=getchar()) != EOF);
while( (s2[j]=getchar()) != EOF);
(3) The terminating ^Z characters should be removed from s1 / s2 (you might also want to remove the 0x0A (line feed)).
(4) The debug statements are outputting characters, not strings, so the printf() format string should be "\n%c", not "\n%s".
Cleaning up your code gives the following working version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RANGE 10
int any(char [], char []);
int main()
{
char s1[RANGE];
char s2[RANGE];
int i,j;
i = j = 0;
while( (s1[i++]=getchar()) != EOF);
s1[i-2] = 0;
while( (s2[j++]=getchar()) != EOF);
s2[j-2] = 0;
printf("%d", any(s1, s2));
}
int any(char s1[], char s2[])
{
int i,j;
for(i=0;s1[i]!='\0';i++)
for(j=0;s2[j]!='\0';j++)
{
// for debug
printf("\n%c", s1[i]);
printf("\n%c", s2[j]);
//
if(s1[i]==s2[j])
return i;
}
return -1;
}
The output for 'aaaa^Z' / 'bbbb^Z' is:
// for debug
printf("\n%s", s1[i]);
printf("\n%s", s2[j]);
%s signifies that the argument is a string (aka char*) but you are actually passing just a char.
Try this:
// for debug
printf("\n%c", s1[i]);
printf("\n%c", s2[j]);

Resources