6

I was wondering if there is a way to make char* point to the contents of a char array so that I can modify the char* across functions.

For example

void toup(char* c) {
  char array[sizeof(c)];
  for (int x;x<strlen(c);x++){
    array[x]=toupper(c[x]);
  }
}

int main(){
  char *c="Hello";
  toup(c);
}

Trying to make the array = char* does not seem to work. Is it possible to make the char* point to the char array?

jww
  • 83,594
  • 69
  • 338
  • 732

4 Answers4

8

Is it possible to make the char* point to the char array?

Yes. Instead of:

int main(){
  char *c="Hello";
  toup(c);
}

Use:

int main(){
  char c[] = "Hello";
  toup(c);
}

char *c = "Hello"; makes the string const and usually puts the string in a const data section. char c[] = "Hello"; provides the mutable string you want.

Also see Why is conversion from string constant to 'char*' valid in C but invalid in C++.


Also see Blaze's comment:

for (int x;x<strlen(c);x++) x is uninitialized. Did you mean int x = 0?


Two other caveats...

void toup(char* c) {
  char array[sizeof(c)];
  for (int x;x<strlen(c);x++){
    array[x]=toupper(c[x]);
  }
}

First, toup is modifying a local array. It is not visible outside the function.

Second, sizeof(c) yields either 4 or 8 since it is taking the size of the pointer. That means the declaration is either char array[4]; on 32-bit machines, or char array[8]; on 64-bit machines.

array[x]=toupper(c[x]); should segfault when the length of string c is larger then the pointer.

You should probably do something like:

void toup(char* c) {
  for (size_t x=0;x<strlen(c);x++){
    c[x]=toupper(c[x]);
  }
}

A similar question is at How to iterate over a string in C? Also see What is array decaying?

jww
  • 83,594
  • 69
  • 338
  • 732
3

No need for temporary buffer array - you already have stream of characters in input.

#include <stdio.h>
#include <ctype.h>

void toup(char* c) {
  for (char * it = c; *it !='\0'; it++){
    *it = toupper(*it);
  }
}

int main(){
  char c[] = "Hello";
  toup(c);
  printf("%s\n",c);
}
Agnius Vasiliauskas
  • 10,413
  • 5
  • 46
  • 66
3

Your toup function has problems:

  1. char array[sizeof(c)] here sizeof(c) is the size of a pointer, not the string.
  2. int x is not initialized in the for loop.
  3. x < strlen(c) is very very very inefficient. You are calculating the length every iteration and strlen is an expensive function.

And in the main function, char *c="Hello"; is not valid C++. You meant char c[] = "Hello"

Here's is one way to do this:

#include <iostream>
#include <algorithm>
#include <cctype>

int main() {
  char str[] = "Hello World";
  std::for_each(std::begin(str), std::end(str),
    [](char& c) { c = std::toupper((unsigned char)c); });
  std::cout << str << '\n';
}
Ayxan Haqverdili
  • 17,764
  • 5
  • 27
  • 57
  • 1
    Since you are using C++11 (implied by `std::begin`) , I'd write that for_each as `for (char &c: str) { c = std::toupper((unsigned char)c); }`. Unless you want to iterate over part of a container, `for_each` is not very useful now. – Martin Bonner supports Monica Aug 23 '19 at 08:18
  • @MartinBonner I think it is sensible to prefer STL algorithms over hand-rolled loops. They may be optimized and are less error-prone. Also, if needed, OP can replace `std::for_each` with something like `std::transform` very easily. – Ayxan Haqverdili Aug 23 '19 at 08:34
  • I strongly disagree. Algorithms are one of the ugliest parts of the standard. You can do some amazingly clever things with them - but doing so results in code which is almost impossible to read. I don't care about optimization (and the compiler will generate the same assembler in both cases anyway). – Martin Bonner supports Monica Aug 23 '19 at 08:40
  • @Ayxan If you don't use a specialized algorithm, you should prefer range-based for loop over `std::for_each`. It essentially does the same thing but it easier to read (less noise) *(and also a bit less error prone as you specify the container once and don't explicitly specify begin and end.)* – Phil1970 Aug 24 '19 at 14:29
-1

To get a pointer to a char array:

char *ptr = array;

To then use values from it (i.e. printf)

printf(“%c\n”,*(ptr + i));

make sure to dereference ptr by using *

fugiefire
  • 318
  • 1
  • 8
  • Hmm... your use of double quotes - `“` and `”` - will surely cause a compile failure. I don't know of any C compilers that accept them. – jww Aug 23 '19 at 08:59
  • @jww ah I was writing on my phone, it made it into those quotes. – fugiefire Aug 23 '19 at 09:16