Getting a segmentation fault in my code - c

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

Related

returning string of chars in C

i compiled my piece of code and it worked fine using printf , but i want it to be returned without being printed ..
char *ft_strrev(char *str)
{
int i = 0;
while (str[i] != '\0')
{
i++;
}
while (i != 0)
{
i--;
}
return str;
}
int main ()
{
char *string;
string = "amrani";
ft_strrev(string);
}
The main thing here is to reverse the input entred ..
how can i exactly use return , to return the full char given to my var string , any tips ?
There are two approaches to doing this: make a new string and return it or mutate the parameter in place. Here's a new string version per your clarification comment. Note that memory is allocated for the new string and the caller is expected to free the result:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *ft_strrev(char *str)
{
int len = strlen(str);
char *reversed = malloc(sizeof(*reversed) * (len + 1));
reversed[len] = '\0';
while (*str != '\0')
{
reversed[--len] = *str++;
}
return reversed;
}
int main()
{
char *string = "amrani";
char *reversed = ft_strrev(string);
printf("%s\n", reversed);
free(reversed);
}
Note that many functions of this kind will include the length of the string as a second parameter so the function needn't call strlen.
This solution inverts the string in place.
#include <stdio.h>
#include <string.h>
char *ft_strrev(char *str)
{
int len = strlen(str);
for (int i = 0; i < len / 2; i++)
{
char temp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = temp;
}
return str;
}
int main()
{
char string[] = "amrani";
ft_strrev(string); // return value of ft_strrev not used here
printf("%s", string);
}
Be aware of the difference betwween this:
char string[] = "amrani"; // string is an array of chars initialized with "amrani"
and this:
char *string = "amrani"; // string is a pointer to the string literal "amrani"
Modifying a string literal results in undefined behaviour, most likely some crash on modern platforms.

segmentation fault (core dumped) error in C program

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.

conflicting types for function returning a char array

Here's my code:
#include <stdio.h>
#include <string.h>
char input_buffer[1000];
void get_substring(){
int i;
int length;
printf("Please enter a string:\n");
scanf("%[^\n]s", input_buffer);
printf("Index of first character of substring:\n");
scanf("%d", &i);
printf("Length of substring:\n");
scanf("%d", &length);
printf("Substring is %.*s ", length, input_buffer + i);
}
int main(void) {
// your code goes here
//get_substring(0,4);
get_substring();
return 0;
}
That's my current code, I want to return a pointer of the input, instead of just displaying the substring. Sorry for the confusion everyone.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* getSubstring(char* str,size_t start, size_t length)
{
// determine that we are not out of bounds
if(start + length > strlen(str))
return NULL;
// reserve enough space for the substring
char *subString = malloc(sizeof(char) * length);
// copy data from source string to the destination by incremting the
// position as much as start is giving us
strncpy(subString, str + start, length);
// return the string
return subString;
}
int main(int argc, char* argv[])
{
char *str = "Hallo Welt!";
char *subStr = getSubstring(str,0,20);
if(subStr != NULL)
{
printf("%s\n",subStr);
free(subStr);
}
}
This solution should give you a hint how you would start with such a problem.

Find bug in the C Program to Reverse a String

I have written the following code to reverse a String. But it is giving some error. It get stuck after calling the reverseStr() function. I am unable to find the bug. Can someone help me?
#include <stdio.h>
#include <stdlib.h>
char * reverseStr(char *str){
int i,len = 0;
while(str[len]!=NULL){
len++;
}
len-=1;char temp;
for(i=0;i<len/2;i++){
//printf("%d %d %s\n",i,len,str);
temp = str[len-i];
str[len-i]=str[i];
str[i]=temp;
//printf("%d %d %s\n",i,len,str);
}
return str;
}
int main(void) {
char *str = "abcdefg";
printf("Original :: %s\n",str);
str = reverseStr(str);
printf("Reversed :: %s",str);
return 0;
}
char *str = "abcdefg";
will place string literal "abcdefg" in the read-only section of the memory and making str to point to that, any writing operation on this memory illegal and hence the runtime error.
Use char str[] = "abcdefg" ; and simply reverseStr(str);
Now you can't do str = reverseStr(str) ; here since types are different, you can store the result in another char pointer though.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void reverseStr(char *str){
int i,len;
len = strlen(str);
char temp1,temp2;
int j = len - 1;
for(i=0;i<j/2 + j%2;i++){
printf("%d %d %s\n",i,j,str);
temp1 = str[j-i];
temp2 = str[i];
str[i]=temp1;
str[j-i]=temp2;
printf("%d %d %s\n",i,j,str);
}
return;
}
int main(void) {
char str[10];
strcpy(str,"abcdefgh");
printf("Original :: %s\n",str);
reverseStr(str);
printf("Reversed :: %s",str);
return 0;
}

Printing a C string in reverse without using pointers?

Is there a way to print a string of fixed size in reverse without using pointers?
#include<stdio.h>
main()
{
char buffer[10];
scanf("%s", buffer);
// need to print buffer in reverse without using pointers??
}
A lovely K&R function to reverse your string in-place before printing it, perhaps?
#include <stdio.h>
#include <string.h>
void strrev(char *s) {
int tmp, i, j;
for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
int main(int argc, const char *argv[]) {
char buffer[10];
scanf("%s", buffer);
strrev(buffer);
printf("%s\n", buffer);
return 0;
}
#include<stdio.h>
main()
{
char buffer[10];
int n = scanf("%s", buffer);
// print the number of chars written to buffer
if (n != EOF) {
int len = strlen(buffer);
if (len <= 10) {
int i;
for (i = len - 1; i >= 0; i--)
printf("%c", buffer[i]);
}
}
}
Since [] is just syntactic sugar for pointers, here's a version that works completely without pointers, arrays or anything else, just one single int. You didn't say that the string has to be stored somehow. :) (Note that I use fgetc instead of a buffer and scanf).
[jkramer/sgi5k:.../c]# cat rev.c
#include <stdio.h>
#include <stdlib.h>
void read_print();
int main(void) {
fputs("Enter your string, yo! ", stdout);
read_print();
fputs("\nDone!\n", stdout);
return EXIT_SUCCESS;
}
void read_print() {
int c = fgetc(stdin);
if(c != EOF && c != '\n') {
read_print();
fputc(c, stdout);
}
}
[jkramer/sgi5k:.../c]# gcc -o rev rev.c -Wall -W -Os
[jkramer/sgi5k:.../c]# ./rev
Enter your string, yo! foobar
raboof
Done!
Here's a recursive way of doing it; technically, this is using a pointer, but I wouldn't go into language-lawyer mode with such simple tasks.
#include <stdio.h>
/* If you want it printed forward, or backward, or think of another way.. */
typedef enum {
FRONT = 1,
BACK,
} direction;
/* Technically still using a pointer...don't nitpick. */
void echo_string(char buffer[], size_t buflen, direction from)
{
/* An index into the buffer to echo, which will preserve
* its value across subsequent recursive calls.
*/
static size_t index = 0;
/* According to the specified direction, print from the front
* or the back of the buffer. Advance the index (a misnomer, I guess).
*/
if(from == FRONT) {
printf("%c", buffer[index++]);
}
else {
printf("%c", buffer[buflen - ++index]);
}
/* Are there any more characters to echo? Yes? Awesome! */
if(index != buflen) {
echo_string(buffer, buflen, from);
}
}
int main(int argc, char **argv)
{
char buffer[10];
scanf("%s", buffer);
/* Better strlen() than sizeof() here,
* but BEWARE! scanf() is DANGEROUS!
*/
echo_string(buffer, strlen(buffer), BACK);
return(0);
}
reverse(char c[], int len)
{
if( ! (len / 2))
return;
char t = c[0];
c[0] = c[len--];
c[len] = t;
reverse(c, len-1);
}
The error(s) is left as an exercise to the student.
As caf pointed out, we're still using pointers..!
Here's an other way to solve the problem (of reversing a string).
This code snippet (and probably most others) don't respect stuff like utf8. I think signines post demonstrating the K&R way was quite close to mine (:D) so I adapted mine to fit that example (and corrected some things..)
#include <stdio.h>
#include <string.h>
void strrev(char *s) {
size_t len = strlen(s) + 1;
size_t i, j;
for(i = 0; i < len / 2; i++) {
j = len-1 - i-1;
char tmp = s[j];
s[j] = s[i];
s[i] = tmp;
}
}
int main(int argc, const char *argv[]) {
char buffer[10];
scanf("%s", buffer); // Look out for an overflow ;)
strrev(buffer);
puts(buffer);
return(0);
}
You can use strrev to reverse a string.
#include <stdio.h>
#include <string.h>
main()
{
char buffer[10];
scanf("%s", buffer);
strrev(buffer);
printf("%s", buffer);
}
void outstrreverse(const char s[])
{
size_t l=strlen(s);
while( l && s!=&s[--l] )
putchar(s[l]);
if(s[0])
putchar(s[0]);
}
Because of the relationship between C strings, arrays, and pointers the exercise is rather shotty IMHO - the most idiomatic description of a "String" in C is represented by the char*, which is not an array. Your (the OPs) title and post differ in their definitions between string and char[fixed length].
The OP should read and understand this FAQ entry, and between that and the posts here: easily figure out a solution—as well as defend it to the teacher/judge if need be.
I'll comment on this: never use scanf("%s", buffer) to populate a fixed length string. If you must use scanf() to do it, please use a field width specifier: e.g. scanf("%9s", buffer); if buffer is an [10], you want a specifier of 9 because of how scanf fills the buffer: otherwise you must beware the dragons! You could also scanf by character and evade the issue with a loops bounds, but that would likely be less efficient.
#include <stdio.h>
#include <conio.h>
void reverse(char a[], int s, int sc );
void reverse(char a[], int s, int sc ){
if ((sc-s)<(s-1))
{
a[sc-s]^=a[s-1];
a[s-1]^=a[sc-s];
a[sc-s]^=a[s-1];
reverse (a, s-1, sc) ;
}
}
void main (){
char a[]="ABCDEFG";
reverse(a, 7, 7);
printf("%d",a);
getch(); //i just use it to freeze the screen
}

Resources