Manipulate Array Outside Main [duplicate] - c

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 7 years ago.
I am trying to write a simple encryption program (Caesar cipher) and I am running into a snag. I am relatively new to the world of C and pointers, coming from Java originally.
Whenever I run the following code, it will give me the error message Segmentation fault and terminate.
I have done a little reading about what that means, but I still don't fully understand it, or what is wrong with my code, or how to remedy the issue.
If you could help with any of those things that would be greatly appreciated.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
void encrypt(char *input);
int main()
{
char *instructions = "pipi";
encrypt(instructions);
printf("Here are your secret instructions:\n%s\n", instructions);
return (0);
}
void encrypt(char *input) {
while (*input != '\0') {
if (isalpha(*input)) {
*input += 1;
if (!isalpha(*input)) {
*input -= 26;
}
}
input++;
}
}

String literals in C, like "pipi" are read only, trying to modify such a string will lead to undefined behavior.
Use an array if you want to modify the string:
char instructions[] = "pipi";

Related

why does passing C string into function as char* cause runtime error (but passing C string defined as char[] is ok)? [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 2 years ago.
I have a simple C program as follows:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void convertToUpperCase(char* sPtr);
int main(int argc, char** argv) {
char myString[] = "cHaRacTerS aND $32.95";
char* anotherString = "cHaRacTerS aND $32.95";
convertToUpperCase(myString); // THIS IS OK!
convertToUpperCase(anotherString); // THIS CAUSES RUNTIME ERROR
// (ie. build success but run fail)!
return (EXIT_SUCCESS);
}
void convertToUpperCase(char* sPtr) {
while (*sPtr != '\0') { // current character is not null (ie. end of string).
*sPtr = toupper(*sPtr); // turns valid characters into upper case
++sPtr; // point to next character within the string.
}
}
It seems like passing anotherString into the function that expects a char* is the problem. From my understanding, both myString and anotherString are char* in C.
It seems to me the problem is how they are defined. For myString I defined it as an array of characters with a null terminator at the end. For anotherString it is a character pointer to a string literal somewhere.
But I can't figure out why the way they are defined matters in this situation.
Thanks in advance :)
edit: used specific terms as suggested by answers.
Because when you declare a literal, it is read only.
char myString[] = "cHaRacTerS aND $32.95"; // readwrite memory
char* anotherString = "cHaRacTerS aND $32.95"; // placed in readonly memory
Edit: to clarify, it is not only read-only, it is UB to write to a string literal. Thanks for that comment, #chux-reinstate-monica

How to pass array "by reference" in C? [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 6 years ago.
This is what I'm trying to do but my code is either not compiling or giving me an unexpected output "BC" instead of just "B".
#include <stdio.h>
void removeFirstAndLastChar(char** string) {
*string += 1; // Removes the first character
int i = 0;
for (; *string[i] != '\0'; i++);
*string[i - 1] = '\0';
}
int main(void) {
char* title = "ABC";
removeFirstAndLastChar(&title);
printf("%s", title);
// Expected output: B
return 0;
}
I looked through a lot of answers here related to passing pointers by reference but none of them seemed to contain the operations that I want to do in my removeFirstAndLastChar() function.
I do not judge your algorithm or C conventions, friends who comment on your problem are totally right. But if you still do it in this way you can use this approach.
#include <stdio.h>
#include <string.h>
void removeFirstAndLastChar(char* string) {
memmove(string,string+1,strlen(string));
string[strlen(string)-1]=0;
}
int main(void) {
char title[] = "ABC";
removeFirstAndLastChar(title);
printf("%s", title);
// Expected output: B
return 0;
}

assigning a char to a string [duplicate]

This question already has answers here:
why this program doesn't give the expected output? [duplicate]
(2 answers)
Closed 7 years ago.
I'm stuck here trying to understand why this assignement can't work in this way in C. What I'm trying to do is substitute all space occurrences with underscore char. (output: Hi_from_Synchronyze)
I saw that the problem comes when I try to do this..
s[n]='_';
the complete code is this one
#include <stdio.h>
#include <stdlib.h>
char *underscore(char *s, int n);
int main()
{
printf("%s", underscore("Hi from Synchronyze", 0));
return 0;
}
char *underscore(char *s, int n)
{
if(s[n]=='\0')
return s;
else {
if(s[n]==' ') {
s[n]='_';
return underscore(s, n+1);
}
else return underscore(s, n+1);
}
}
I'd like to know what's going on behinde and why this happens, not the solution.
Thank you very much in advance
String literals are read-only, so you can't assign to them.
Make a mutable copy of the string first, something like:
char text[] = "Hi from Synchronyze";
printf("%s", underscore(text, 0));

Segmentation fault (core dumped) in a C program [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Segmentation fault (core dumped) in a simple C code
(3 answers)
Closed 8 years ago.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *Change(char *str,int start,int end)
{
if(start==end || start>end){
return str;
}
else{
char temp=str[start];
str[start]=str[end];
str[end]=temp;
return(Change(str,start++,end--));
}
return str;
}
char *Reverse(char *str)
{
int length=strlen(str);
return(Change(str,0,length-1));
}
int main()
{
printf("%s\n",Reverse("program"));
return 0;
}
I am trying to write a recursive function to reverse a string,but it comes the linking error.Please help.I had tried so many times and searched in the Internet,but it can't help.
I guess the most probably place causing the problem is in function Change,but I can't solve with it.
You're passing a string literal (which is a const char*) to Reverse(), since you can't modify a string literal, your program generates a segmentation fault.
You'll either need to pass a modifiable string to Reverse():
char myStr[] = "program";
printf("%s\n",Reverse(myStr));
Or you can make a copy of the input string in Reverse():
char *Reverse(const char *str)
{
int length=strlen(str);
char* temp = malloc(length);
strcpy(temp, str);
return(Change(temp,0,length-1));
}
In that case, you'll need to free the string returned by Reverse():
char* reverseStr = Reverse("program");
printf("%s\n", reverseStr );
free(reverseStr);
Also in change(), start++ end end-- will return the value before they are incremented, you need to use either ++start or simply start+1 since you won't use those variables anymore:
return(Change(str,start+1,end-1));
Simple explanation: You can't modify a string literal. One more thing is that the statement
return(Change(temp,0,length-1));
will cause compilation error because neither temp is defined in the function Reverse nor it is globally defined.

segmentation fault run time error [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 9 years ago.
i have written a code . this looks as follows .
#include<stdio.h>
#include<string.h>
int do_print2(char *q[]);
int main()
{
char *p[]={"pointervaule","NAM", "JAM", "CALM"};
do_print2(p);
return 1;
}
int do_print2(char *p[])
{
printf("this is print1 char *p \n");
strcat(p[0],"added");
printf("%s\n", (p[0]));
return 1;
}
after compilation, i am trying to run it, i am getting segmentation fault. help me in learning what is the reason for that error. thank in advance.
In your code: strcat(p[0],"added"); try to write on read only memory that is illegal in C. Because p[0] points to a constant string.
Not p is pointer to char array, but not 2-dimensional char array.
Read: Difference between char* str[] and char str[][] and how both stores in memory? an answer with diagrams and code examples, to understand it better.
The OS says that the C strings are in the read section of the object (i.e. protected from writing).
Due to historical reasons "bla bla" is really a const char * const data type, but is allowed to get away in the C compilers eyes some teenage interdependencies. But the headmaster (OS) is less forgiving and expels the running of such code in the corridors. (how many metaphors in that statement).
You can't write to read only memory, better way to do this:
#include<stdio.h>
#include<string.h>
int do_print2(char q[][20]);
int main()
{
char p[4][20] = {{0}, {0}, {0}, {0}};
strcat(p[0],"pointervaule");
strcat(p[1],"NAM");
strcat(p[2],"JAM");
strcat(p[3],"CALM");
do_print2(p);
return 1;
}
int do_print2(char p[][20])
{
printf("this is print1 char *p \n");
strcat(p[0],"added");
printf("%s\n", (p[0]));
return 1;
}

Resources