Pass and edit specific character in string - c

I'm trying to pass in a memory reference to a character in a string and edit it in a function using C. The code is below:
void EditChar(char *input) {
printf("# %s #",*input);
*input = *input << 1
}
int main() {
char *string ="aaaa";
EditChar(&string[2]);
printf("%s",string);
}
I can print the character inside the function fine which I presume must mean it's following the pointer so why am I unable to edit the pointer location of that character, any ideas?

The lack of a ; on line 3 is going to cause problems to start with.
You're passing a character instead of a character pointer on line 2.
And on my mac, once you fix those problems, you get a bus error on line 3 because you're trying to change read-only memory.
char *string =strdup("aaaa");
and now it works.
Also, as stated in question comments, instead of strdup, you may want to use
char string[] = "aaaa";

Related

Passing string by value in C

After going through multiple examples of passing a string by value in C, I still don't understand why the following code does not work
int main(void){
char *fileList;
strcpy(fileList,"This is a test line\n");
char type = 'F';
if(checkFileList(fileList, type)){
printf("Proper File list\n");
}
else{
printf("Improper File list\n");
}
}
int checkFileList(char *string, char type){
// Do something with string
}
This program works if I define the variable fileList in the main function as-
char fileList[128];
But I can't provide a fixed size to this string as I get the string only at runtime and hence don't know how long it'll be.
What am I doing wrong here? Please note that I don't want to pass the string by reference as I'll be changing the string in the function and don't want this to be reflected in the original string.
In your code
char *fileList;
strcpy(fileList,"This is a test line\n");
invokes undefined behaviour
, as , fileList is used uninitialized.
You need to allocate memory to fileList before using it. Maybe malloc() and family of functions will help you into that. Also, read about free().
FWIW,
This program works if I define the variable fileList in the main function as-
char fileList[128];
because, the fileList is an array here and the memory allocation is already done by the compiler. So, it is ok to use that.
BTW "Passing string by value" is misuse of the terms. C uses pass-by-value for any function parameter passing.
In order to allocate the memory for the string at runtime you better get to know the size of the string first:
int main(void){
const char *str = "This is a test line\n";
int len = strlen(str);
char *fileList = malloc(len);
// then later you also have to take care for releasing the allocated memory:
free(fileList);
}

Why am I getting segmentation fault while dynamically allocating in c?

This is my code and when I run it, I am getting segmentation fault.
char *s = NULL;
s = (char *)malloc(5*sizeof(char));
s[0]='10';
s[1]='20';
printf("%s",s[1]);
please tell where the error is and why this is happening. My intension of the program is to dynamically create a string, give it some value byte by byte and print the values byte by byte.
Is there any way to add integer values to string. Because, I have a situation where length of string is to be in first part of string followed by data. Kindly suggest any method to do this in C.
printf("%s", s[1]); means print string starting at address (int)'20'. That's clearly a bug. Should be: s[2]='\0'; printf("%s", s+1 /*&s[1]*/);
You are storing multibyte characters in s[0] and s[1]. Beside of this use %c format specifier to print a character.
1.s[0] is a char you can not assign 10 to it. (It will compile with warnings but it is not doing what you have expected)
2.printf("%s",s[1]); will also cause undefined behavior as string followed bys[1] is not null terminated.
Don't cast the result of malloc and family.
s[0] and s[1] will take only one byte value.
Then your string is not a null terminated string.
Try this.
s[0]='h';
s[1]='i';
s[2]='\0';
printf("%s",s);
%s is for printing the string. Use %c for printing the character.
printf("%c",s[1]);
You can use like this to store the integer into an char array,
char *s=malloc(123);
sprintf(s,"%d",integer_value);
Then use strcat to store the string in that.
Passing to the function use like this,
void func(char *);
main() {
. . .
func(s);
. . .
}
void func(char *str)
{
// do what you need
}
if between integer and string slash is available ( like in your comment) you can use the strtok function. Before using the strtok function take backup for your string. It will modify your content. Or els you can use like this,
sscanf(str,"%d / %s",&int,string);
Now string have the value "hello".
char s[10];
sprintf(s,"%d",int);
strcat(str,s);
Try this,
int fd;
char str[]="data7";
char st[12];
sscanf(str,"%[^ 0-9] %d",st,&fd);
printf("st:%s\tfd:%d\n",st,fd);

Copy a word from a function to a string with strcpy in C?

I'm in a basic C programming course and I'm trying to create a hangman game. I've been stuck with a problem for the last three hours and I'm not getting any wiser.
Basically, I've created a function which reads a random line from a text file and then copies it to a string. Afterwards, I want to copy that string to another string outside off the function. This is because the main game is supposed to be completely built with functions.
This is the function that reads a random word from the text file and copies it to a string:
char datorns_val()
{
char ordlista[20];
char valt_ord[20];
int raknare = 0;
srand(time(NULL));
random = rand()%10+0;
ptr_file =fopen("hangman.txt","r");
if (!ptr_file)
{
return 1;
}
while (fgets(ordlista,20, ptr_file)!=NULL)
{
raknare++;
if (raknare == random)
strcpy(valt_ord, ordlista);
}
return valt_ord;
}
After this is done, I want to copy the word located in valt_ord to another string, and that's when I'm unsure about what to do:
char word[20];
strcpy(word,datorns_val());
I'm getting two errors that says:
Invalid conversion from 'char' to 'const char*'
and
initializing argument 2 of 'char* strcpy(char*, const char*)'
Am I on the right track here with using strcpy() twice or am I completely lost? I tried my build without a function structure and simply typing out all the code on after another and it works, if a replace the second strcpy() with a simple char word = valt_ord.
Thanks, Jonathan
(Sorry if my code is hard to understand, I'm swedish and my second language is English)
Currently you're returning a character, which is not of much use, since you need a string that will outlive the function which creates it. You should return a dynamically allocated string (using a pointer) for this.
char* datorns_val()
{
// ... your current code
char *ret_str = malloc(20);
strcpy(ret_str, valt_ord);
return ret_str;
}
At the end where you use it, you should free it when done.
char *result = datorns_val();
// use result
free(result);
result = NULL;
Alternatively, if you're sure that the function which is calling the datorns_val is the only one which is going to use the result, then I'd recommend something else which doesn't involve dynamic memory alloc/decalloc (malloc/free). Pass the string to be loaded to datorns_val.
int datorns_val(char (*str_ptr)[20]) // pointer to an array of 20 chars
{
// use str_ptr after dereferencing it to get back the char array
// say you want to copy "abc" to it
strcpy(*str_ptr, "abc");
return 0; // to denote success, you may return -1 for failure
}
// caller's end
char result[20] = "";
int success = datorns_val(&result); // pass the array by reference
Read more about arrays and pointers to know more about them.
Your function datorns_val is declared to return char while in fact it returns valt_ord that is of type char[]. Also there is a way bigger problem valt_ord is a local variable so even if you change the declaration the code will not work. You will need to allocate valt_ord dynamically(using malloc) or to pass it as function argument.
argument 2 of strcpy needed string but your function returning char.
man strcpy.
you trying to return local variable, it will be destroyed when you move out of function because it stores the data in stack. Use malloc
see this SO question for further clarification

strcat in C error segmentation

#include <stdio.h>
#include <string.h>
int main() {
char tab[2]={"12"};
FILE *outfile;
char *outname = "/home/dir/";
printf("%s", strcat(outname,tab));
outfile = fopen(strcat(outname,btab), "w");
if (!outfile) {
printf("There was a problem opening %s for writing\n", outname);
}
}
I have this error: Segmentation Fault.
How can I fix it?
At least two errors:
char tab[2] = {"12"};
You'd better use tab[3] or even better tab[] -- you need one extra char for the terminating NUL character.
Also,
char *outname = "etc...";
creates a constant string in the data segment of the executable -- it can't be overwritten, since strcat is using its first parameter to concatenate the two strings. So when strcat() tries to do so, it segfaults. Use
char outname[50]; // something big enough
strcpy(outname, "/home/dir");
instead.
outname is a string literal and string literals are not modifiable. Modifying a string literal is undefined behavior.
outname is Const pointer so once you have entered some thing in it, you can't modify it.
However if you want to copy things in it, make a char array of the size equal to tab[] array because here the size of string to be copied is known. Most of the time char pointers like OUTNAME are used when you are taking input from a user once and you don't know how long that input will be.
In your code,
char *outname = "/home/dir/";
outname is a string literal and hence when used with strcat, it does not have enough length to hold the concatenated string.This results in segmentation fault.
Same is the case had you declared it as below,
char outname[] = "/home/dir/";
The solution for this to declare the size of the outname big enough to hold the concatenated string.
char outname[80] = "/home/dir/";

Different results using %c and loop vs. %s in printf with null terminated string

I have a variable 'jmp_code' that is declared as a char *. When I run the following commands
printf("char by char, the code is '%c%c%c%c'\n", *jmp_code, *(jmp_code+1), *(jmp_code+2),*(jmp_code+3));
printf("printing the string, the code is '%s'\n", jmp_code);
I get the following results
char by char, the code is '0,0,0, ,'
printing the string, the code is 'ö\├w≡F┴w'
I am using codeblocks. Here is the sample code I am playing with.
#include <stdio.h>
#include <string.h>
char * some_func(char * code);
char * some_func(char * code) {
char char_array[4];
strcpy(char_array, "000");
code = char_array;
return code;
}
int main ( void ) {
char * jmp_code = NULL;
jmp_code = some_func(jmp_code);
printf("char by char, the code is '%c,%c,%c,%c,'\n", *jmp_code, *(jmp_code+1), *(jmp_code+2),*(jmp_code+3));
printf("printing the string, the code is '%s'\n", jmp_code);
return 0;
}
I am quite confused by this. Any help would be appreciated.
Thanks
Some quick observations:
char * some_func(char * code) {
char char_array[4];
strcpy(char_array, "000");
code = char_array;
return code;
}
You can't assign strings using = in C. That messes things up - you're assigning code the pointer of your locally allocated char_array to code, but you're not copying the contents of the memory. Also note that since char_array is allocated on the stack (usually), you'll find it disappears when you return from that function. You could work around that with the static keyword, but I don't think that's the nicest of solutions here. You should use something along the lines of (big warning this example is not massively secure, you do need to check string lengths, but for the sake of brevity):
void some_func(char * code) {
strcpy(code, "000");
return;
}
(Refer to this (and this) for secure string handling advice).
And call it via some_func(jmp_code) in main. If you're not sure what this does, read up on pointers.
Second problem.
char * jmp_code = NULL;
Currently, you've declared space enough for a pointer to a char type. If you want to use my suggestion above, you'll need either to use malloc() and free() or else declare char jmp_code[4] instead, such that the space is allocated.
What do I think's happening? Well, on my system, I'm getting:
and the code is '0,0,0,,' and the code
is ''
But I think it's chance that jmp_code points to the zeros on the stack provided by your some_func function. I think on your system that data has been overwritten.
Instead you're reading information that your terminal interprets as said character. Have a read of character encoding. I particularly recommend starting with The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
You're returning a reference to a temporary array. char_array goes away when some_func() retuns, but you keep using the address of it. You need to use malloc() to allocate an array and then free() it after you use it.
You're printing from an invalid pointer. char_array is on the stack of some_func() function.
The function returns the pointer of something that is on the stack and will be no more after the function returns!
The first printf finds the stack still unchanged, the second, maybe, found it filled with... garbage!
It might be interesting to see:
const char *pos = jmp_code;
while (*pos)
printf("%d ", *pos++);
I think char type can not use non-ascii char codes. Meaning your string contains UTF-8 or like symbols which code could be in (0, over9000) range, while char codes could be in (0, 255) range.

Resources