Converting a character pointer to uppercase in C - c

I have a pointer:
char * name;
it contains the string "test:case"
And I'm calling another function with it, and trying to store it in a structure. However, I want to capitalize the entire string first, but It doesn't seem to work.
void func(char * name) {
int i;
List * l;
l = malloc(sizeof(List));
for(i=0; i< strlen(name); i++) {
name[i] = toupper(name[i]);
}
l->name = name;
//CALL A FUNCTION TO LATER FREE ALLOCATED MEMORY
}
Where List is a struct that has a member (char *) named name.
This however, seg faults. I can't go about using non pointers in my case. As I have to use pointers and not character arrays, I'm trying to use toupper in every value of the char pointer, however this doesn't seem to work.

You're getting a segfault because the original string is presumably a literal, and it's not modifiable. You need to make a copy of it first.
void func(char * name) {
List * l;
l = malloc(sizeof(List));
name = strdup(name); // make a copy of name
for (char *p = name; *p; p++) {
*p = toupper(*p);
}
l->name = name;
}
Note that when you later free l, you'll first need to free l->name.

Since you only set the pointer l->name to name, this will crash the moment the original name is no longer there (maybe it was only on the stack?) and l->name is accessed. You need to malloc() space the size of strlen(name)+1, copy name there and set l->name to that address.

You have allocated the List, but not the name string itself.
You need to do:
l=malloc(sizeof(List));
l->name=(char*)malloc(strlen(name)+1); // You need to cater for the the final null char.
There are a few additional issues with your code, here is the correct one (didn't compile it, probably close to okay):
void func(char *name) {
List * l;
l = (List*)malloc(sizeof(List));
l->name = (char*)malloc(strlen(name)+1);
for(char *r=name, char *w=l->name; *r; ++r,++w) {
*w = toupper(*r);
}
*++w='\0';
}
And at every iteration, this code does not evaluate again and again strlen, which would be very bad.

There are two mistakes in the code.
char * name
The variable name contains a pointer to a string (i.e., an array of char).
When you write this:
name[i] = toupper(name[i]);
you are changing the original char itens of the string, if it is not a pointer to a constant string. If that is the case, it is a segmentation fault.
The other mistake is here:
l->name = name;
You are just assigning to the variable within the structure the pointer which was passed on through the variable name to the function. You should make a copy, like this:
strcpy(l->name, name);
This functions copies all the contents from the second argument to the first.
But that's not a good solution. If name contains a pointer to a constant string, it's still segmentation fault.
I'll rewrite your code:
void func(char * name) {
int i;
List * l;
l = malloc(sizeof(List));
char *buffer[strlen(name)]; //buffer of the contents pointed by *name* to upper case, initialized as empty string
for(i=0; i< strlen(name); i++) {
buffer[i] = toupper(name[i]);
}
buffer[i] = '\0'; //closing the string in i = strlen(name)
strcpy(l->name, buffer);
//CALL A FUNCTION TO LATER FREE ALLOCATED MEMORY
}
That way, you manipulate a copy of the original string, and than you make a copy of the buffer to the variable in the structure.
If you do this:
l->name = buffer;
you're only copying a local pointer, which will be gone with the end of the function.
I suggest you learn more about pointers, arrays and strings in C. In essence, a string is a array of char, with a '\0' in the final position. An empty string s has '\0' in s[0].
Edit: if you're used to languages which makes a copy of the string like this:
string1 = string2
you should always have in mind that, in C, that's pointer assignment. So, in C, that code would have to be written like this:
strcpy(string1, string2);
Hope that helps.

Related

String vs String Literal: Direct assignment or strcpy/strncpy?

I think I have some issue understanding string and string literal.
This is what I learned from my class, when passing to a function, const char * indicates this is a string literal, while char * indicates a string.
Suppose I have a struct declaration:
struct node{
char *name;
struct node *next;
};
and a function, this is the function I want to implement:
void load_buffer(struct node *input_node, char *input_name);
This function is supposed to assign input_name to the struct's member name.
My confusion comes from here. Within the body of load_buffer, should I write:
input_node->name = input_name;
Or I should use strcpy/strncpy to do this?
strcpy(input_node->name, input_name);// Suppose it's safe in this case.
To summarize, I am not sure if I should use direct assignment or strcpy family functions to assign a string/string literal to the member of my struct.
Thanks for help. :)
In case of pointer assignment, pointers in each node will point to same location. Thus nodes will be always pointing to updated value. If you are intended to make each node to contain different input then this approach does not suit your requirement.
input_node->name = input_name;
In case of strcpy, pointers in each node will point to different location. Before to that you need to create memory for each pointer.
input_node->name = malloc(strlen(input_name)+1); //Allocate memory first.
strcpy(input_node->name, input_name);// Suppose it's safe in this case.
To visualize:
... when passing to a function, const char * indicates this is a string literal, while char * indicates a string.
Not exactly. const char * declares that the function will not try to modify the string. So it is perfectly suited for string litteral because they cannot be modified.
For your question, the answer is it depends on your real requirements. But simply storing the passed pointer if dangerous if the struct can persist after the function and if the string can be changed in the caller. Let us look at the following code:
void load_buffer(struct node *input_node, const char *input_name) {
input_node->name = name;
}
struct node nodes[2];
char buf[4];
const char *data[] = { "foo", "bar"};
for (int i=0; i<2; i++) {
strcpy(buf, data[i]); // suppose it is read from somewhere (file, stdin, socket)
load_buffer(node + i, buf);
}
Both node objects will have their name member pointing to the string buf from caller and will both point to "bar" (the content of buf at the end of the loop)!
If you want to keep the value of the string at call time, you should copy it in allocated memory:
void load_buffer(struct node *input_node, const char *input_name) {
input_node->name = strdup(name); // allocation errors should be tested...
}
But you should then free the name member, when the node is no longer in use...
First to address some terminology:
this is a string literal: "I am a string literal"
this is a type: char* (aka pointer to char)
this is also a type: const char* (aka pointer to constant char)
this is the declaration of a variable of type char*: char* str
this is the declaration of a variable of type const char*: const char* cstr
A pointer is not a string literal. A pointer can point to string literal, an array, just to a single element or can be null.
In C a string is a null-terminated char array.
In C you can assign a char* variable to a string literal, but modifying the string literal is illegal, so it is strongly advised to never do that. The reason why this is allowed are historical.
char* a = "asd"; // allowed, but frowned upon
// a points to a string literal, so we can say a is a string
// a is not a string literal
char b = 'x';
char* c = &b;
// c points to a single char
// we cannot say c is a string
char d[10] = "asd";
// d is a char array. Its content is a string, so we can say d is a string.
// d is not a string literal
// the string literal is copied into the array d
char* e = d; // or equivalent char* e = &d[0];
// e points to a string
char f[4] = {'a', 's', 'd', '\0'};
// f is an array. Its content is a string, so we can say f is a string
char* g = f;
// g points to a string. We can say g is a string
char h[3] = {'a', 's', 'd'};
// h is an array. Its content is NOT a string, because the char array is not null terminated
char* i = h;
// i is not a string
And now go through all the above once more, but not replace char with const char and all the comments still stand (except that `const char* a = "asd" is now ok).
And now to the problem at hand.
There are two scenarios:
Each node has its own string and "owns" that string. Each node is responsible for allocating memory for the string and freeing that memory. The string lives as long as the node lives. In this case use malloc and strcpy to create a string for each node. Don't forget to free the string when the node is destroyed. This is the most common scenario and probably what you want.
A node doesn't own its own string, but rather points to an external string. It is not allowed to neither allocate nor free memory for that string. There is another entity responsible for managing the lifetime of that string and making sure the string is alive at least as the node is alive. The string can outlive the node without a memory leak.
For example consider this scenario:
there is a list R of string resources. This list owns those resources. This list would use scenario 1
we need to keep two different sort orders of R. So we have two lists A and B that would use scenario 2: each node in A and B just points to a string of R.

C Why does passing first address of array to char pointer provide whole string?

I'm currently playing around with passing char array to a char pointer. Lots of the examples I see show how you need to allocate the memory that the string pointer will use before copying the char array to it. And when copying, you iterate through the array to store each address into the allocated char pointer.
In the example below I don't initialize the char pointer and neither do iterate through the array. I just pass the pointer of the first element.
int main()
{
char c[10] = "something";
// char* new_c = (char *)malloc(strlen(c)+1);
char *new_c = NULL;
new_c = c;
printf("%s", new_c);
return 0;
}
Why is new_c still printing the entire string? Why do people even bother iterating through the entire array to copy?
Run this program and you will get a clear picture of what is happening
#include <stdio.h>
#include <string.h>
int main(void) {
char c[10] = "something";
char *new_c = NULL;
char new_c_2[10] = "";
new_c = c; // copies address of 'c' to 'new_c'
for(int i=0; c[i]!='\0'; i++) {
new_c_2[i] = c[i]; // copies value of 'c' to 'new_c_2'
}
// Data before changing the value of 'c'
printf("\nData before changing the value of \'c\'\n");
printf("new_c = %s\n", new_c);
printf("new_c_2 = %s\n", new_c_2);
strcpy(c, "changed");
// Data after changing the value of 'c'
printf("\nData after changing the value of \'c\'\n");
printf("new_c = %s\n", new_c);
printf("new_c_2 = %s\n", new_c_2);
return 0;
}
OUTPUT:
Data before changing the value of 'c'
new_c = something
new_c_2 = something
Data after changing the value of 'c'
new_c = changed
new_c_2 = something
char *new_c = NULL;
new_c = c;
These statements are just pointing 'new_c' to the address of 'c'.
So, if you change the value of 'c', and use 'new_c' it will go to the address of 'c' and give the updated value.
We copy the string into another so that we can use the old value even if we change the value of 'c'.
Please refer to call by value and call by reference in C programming for further details.
You say "I don't initialize the char pointer". You do, with
new_c = c;
The array c decays to a pointer, just as if you had passed c directly to printf. And then it is printf which iterates through the array until the zero terminator is found.
Why do people even bother iterating through the entire array to copy?
well, maybe to be sure the original reference isn't deleted/overwritten after a while.
For instance, if the original buffer is a local/automatic variable, which will be invalid after returning from the function.
Or if I just do c[0] = '\0';. new_c doesn't display a thing now because I just killed the only copy of the string.
Both copy & referencing another string through a "shallow" pointer are useful, depending on the use cases.

Copy a string from a pointer to an index within an array of pointers

As stated in the title, I wanted to copy a string from a char pointer to location within an array of char pointers. When doing strcpy(), the output results in seg fault, but don't understand why this occurs.
The abbreviated code has the following:
void make_history(char *entry) {
//static char past_entries[10][10];
static char *past_entries[10];
static int index = 0;
static int array_index = 0;
char *input;
if((input = strchr(entry, '\n')) != NULL)
*input = '\0';
if(strcmp(entry, "history") != 0) {
strcpy(past_entries[index], entry);
*past_entries[index] = &entry;
index = (index + 1) % 10;
array_index++;
}
}
Instead of trying to return a 2d array (which is also very tricky), I thought it would be easier to copy the date from entry to the location within the array of pointers past_entries. Again, strcpy does not work, is there a valid reason as to why this occurs, and a possible workaround or solution to this fix?
Thank you
In your example past_entries is just an array of pointers, but you don't allocate any memory to them (initially pointing to NULL). You then try to write to those locations, hence the crash.
To solve this, just allocate some memory before you try to copy your string to it:
past_entries[index] = malloc(strlen(entry) + 1);
Of course you should not forget to free all of this in the end.
Oh and, remove that line: *past_entries[index] = &entry;. It tries to assign a pointer to a character array to a character.

string updating in c

this is a sample program demonstrating getting a string value from a func
can allocate memory inside called function itself and return
can allocate memory inside calling function and called function just updates it.
i am facing problem with the 2nd way.
is there any workaround?
/*
* main.c
*
* Created on: Sep 6, 2014
* Author: Murtaza
*/
#include<stdio.h>
#include<stdlib.h>
char* someFunc1();
void someFunc2(char* str);
void firstApproach();
void secondApproach();
int main()
{
firstApproach();
printf("\n");
secondApproach();
return 0;
}
char* someFunc1()
{
char *str = (char*)malloc(sizeof(char)*10);
str = "HELLO";
return str;
}
void someFunc2(char* str)
{
str = "Hello";
}
void secondApproach()
{
char *str = (char*)malloc(sizeof(char)*10);
someFunc2(str);
printf(str);
printf("heythere");
}
void firstApproach()
{
char *str;
str=someFunc1();
printf(str);
printf("wassup");
}
Please tell me why the second approach isn't working.
thanks!
my output is:
HELLOwassup
h>heythere
and my expected output should be
HELLOwassup
Helloheythere
void someFunc2(char* str)
{
str="Hello"; //-----the variable str is local to this function, thus it goes out of scope as
// soon as the function returns
}
void secondApproach()
{
char *str=(char*)malloc(sizeof(char)*10);
someFunc2(str);
printf(str); // -------------- here the value inside str is some garbage value.
printf("heythere");
}
CORRECTION :
void someFunc2(char **str )
{
*str = "hello";
}
void secondApproach()
{
char *str=(char*)malloc(sizeof(char)*10);
someFunc2(&str); // pass the address of the string
printf("%s", str);
printf("heythere");
}
Let's take a closer look at someFunc2:
void someFunc2(char* str)
{
/* str is a copy of the pointer that was passed in from secondApproach(). */
str = "Hello";
}
Here, you are passing a pointer by value. Thus, str in someFunc2 is a copy of the original pointer str that was passed in from secondApproach(). someFunc2 tells the copy pointer to point somewhere else, but it leaves the original str pointer alone. The solution is to pass in the address of the str pointer then tell someFunc2 to modify the pointer at that address to point to "hello".
void secondApproach()
{
char* str = (char*) malloc(sizeof(char) * 10);
someFunc2(&str); // Pass in the address of str.
printf("%s", str);
printf("heythere");
}
void someFunc2(char** str)
{
*str = "hello";
}
When you write a string between quotes and use it directly as:
a char* -> it gets created in a mutable place in memory, and gives its address to the pointer variable its assigned to. It is still in memory as long as that variable referencing it is not NULL.
an argument -> it gets created as char* and passed to the function (and treated there as a char*), then automatically disposed from memory (i.e. you can't access it or reference it anymore) ..
So, the only situation when a string is actually mutable is when you assign it to a char[], then it gets created in readonly memory and copied into to the stack .. ( the copy on the stack is what the char[] variable will point to )
If you think about it for some time, you realize that this is one of the benefits of dynamic memory: you can create a char* that is mutable, and since it is just a pointer, you don't need to specify the size of the string it is going to point at. So you can see how useful this would be ..
Also, it's worth to note that in functions:
if you pass a string, the variable in the function itself is treated as a char pointer and most likely would try to modify it, and if it's readonly that would raise a Segmentation Fault. So functions are assuming you know what you're doing ..
if you want a function to be able to modify a string directly (i.e string = "somestring") then pass it a pointer to the actual string, else the modification will only be local to the function. That's because the string is a "pointer to char", so the function can't modify the string as a whole. But that also means that a function can modify the string's characters individually ( obviously, because it has a pointer for characters: the string ). If you pass it, however, a string pointer (char**), the function can modify the string directly (*string = "whatever") and can also modify the characters individually (*string[1] = 'C'). Which choice you need depends entirely on the purpose of the function ..
Now, for your specific example, you can do one of two ..
Using a pointer to a pointer to a char (string pointer)
void someFunc2(char** str)
{
*str = "Hello";
}
Using a pointer to char (string)
void someFunc2(char* str)
{
char *k = "Hello";
for(int i = 0; i < 5; ++i)
str[i] = k[i];
}
This is one of the most controversial and advanced topics in C. No matter what type of C programming you're doing, you have to understand these core concepts ..

How does strcpy() copy a string to an array when you can't change the address of an array?

So basically strcpy assigns the address of the 2nd argument to the 1st, but how does it do it with an array as the first argument? like in my program, i tried changing the address of the array but unfortunately it wont compile. So I had to resort to making a character pointer variable to assign the return value of capitalize. Is there something I'm misunderstanding?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char string[20];
char *Capitalize(char *str)
{
int i;
char *temp;
temp = malloc(sizeof(char)*(int)(strlen(str)+1));
for(i = 0;i < strlen(str);i++)
{
if(*(str+i) >= 'a' && *(str+i)<= 'z')
*(temp+i) = *(str+i) - 32;
else
*(temp+i) = *(str+i);
}
*(temp+i) = '\0';
return temp;
}
int main(void)
{
string word;
printf("Enter word to capitalize: ");
scanf("%19s",word);
word = Capitalize(word);
printf("%s",word);
return 0;
}
strcpy() makes a copy, just like the name implies. it's perfectly legal to copy a string in to an array.
When you make an initialization of an array such as:
char myarr[] = "hello";
You're actually copying the characters into the array.
You seem to be confusing arrays with pointers (see here for some reason you can't treat them the same)
In C, qualifying an array by name without an indexer, is equivalent to specifying a pointer to the memory address of the first element in the array, that is why you can pass as a parameter an array to functions like strcpy.
char * strcpy ( char * destination, const char * source );
strcpy will copy whatever series of characters are found, starting at memory address specified by source, to the memory address specified by destination, until a null character (0) is found (this null character is also copied to the destination buffer).
The address values specified in the parameters are not modified, they just specify from where in memory to copy and where to. It is important that destination is pointing to a memory buffer (can be a char array or a block of memory requested via malloc) with enough capacity for the copied string to fit, otherwise a buffer underrun will occur (you will write characters past the end of your buffer) and your program might crash or behave in a weird way.
Hope I have been clear and not confused you more with my explanation ;)
The thing you seem to be missing is that in c/c++ strings ARE arrays, in most practical respects declaring
char c[] = "hello";
and
char* c = "hello";
is the same thing, all strcpy does is copy the characters into the destination memory, whether that memory is allocated as an array (presumably on the stack) or pointer (presumably on the heap);it does not make a difference.

Resources