0

I'm attempting to add a string at the end of another string when im doing a comparison. This how I would do it in java(might not be legit java code - been a while):

String input = "addl $1,%eax";

String[] registers = {"eax", "abx", "ebx", "edx"};
String s = "addl $1,%";

for (int i = 0 ; i < 4; i++) {
    if (input.equals(s + registers[i])) {
        printf("Match");
        // write out optimized code with specified register
    }
}

I'm not sure at all how to do this in C. I've tried the following but my program keeps crashing (i think because of some pointer nonsense):

 ...
 char *in = "Hell";
 char *pattern = "Hello";  
 const char *a[2];
 a[0] = "e";
 a[1] = "o";
 char *result = strcat(in,a[1]);
 if (strcmp(in, result) == 0) {

 printf("Helloooooooooooooooo");

 }

Can anyone enlighten me please how to do this kind of string manipulation in C?

maxdev
  • 2,491
  • 1
  • 25
  • 50
John
  • 317
  • 4
  • 19

5 Answers5

3

You are trying to modify string literal by using strcat. This will invoke undefined behavior. In C, you can't modify a string literal. The declaration

char *in = "Hell"; 

is equivalent to

char const *in = "Hell";  

If you wanna modify it then declare in as an array

char in[6] = "Hell";  

Suggested reading: c-faq: Question 1.32.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    He doesn't modify a string literal, he modifies a constant string. Modifying a string literal (or at least trying to ^^) would be `strcat("hell", "o")` – maxdev Apr 25 '14 at 12:17
  • 1
    @maxdev; What is the difference between a sting literal and a constant string ? – haccks Apr 25 '14 at 12:19
  • @maxdev; I haven't find the term *string constant* in the standard. – haccks Apr 25 '14 at 12:34
  • I downvoted. Your answer explains that a `const char*` can't be modified, but not how to do it right, and why. I made an edit to make clearer but you removed it. – maxdev Apr 25 '14 at 12:38
  • @maxdev; I have not rejected your edit. Others have rejected it. – haccks Apr 25 '14 at 12:40
  • 2
    @maxdev no, he modifies a string literal. There are no constant strings involved here (string literals are not constant, but they are read-only). – M.M Apr 25 '14 at 12:45
  • 2
    @maxdev: Ok, let's end dis back-and-forth semantics dispute: The C standard doesn't mention constant strings but does have a section entitled: **6.4.5 String literals**. Let's conform to the standard, and agree we're talking about string literals here – Elias Van Ootegem Apr 25 '14 at 12:55
1

You're calling strcat on in, which is a pointer to an immutable string literal (a char array in read-only memory). By definition, you can't concatenate any other chars to that array.

I've explained this phenomenon a bit more elaborate here

Just like in the linked question, you could solve this by defining char *in as an array of chars:

char in[MAX_IN_LEN] = "Hell";

Which copies the chars from the string literal into the char array. Then, provided the array is big enough, you can concatenate as much as you want.

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
1

You can try this:

const char *input = "addl $1,%eax";  // For testing the code

char *registers[] = {"eax", "abx", "ebx", "edx"}; 
const char *s = "addl $1,%";
char temp[30];   // temp array to store possible commands in complete form

for (int i = 0 ; i < 4; i++) {
    strcpy(temp, s);  // Copy the common part to `temp`
    if (strcmp(input, strcat(temp, registers[i])) == 0) 
          // Compare the input string with possible command string
    {
        printf("Match");
        // write out optimized code with specified register
    }
}

You can read more about strcpy, strcmp and strcat here

0xF1
  • 6,046
  • 2
  • 27
  • 50
0

The following two statements are different in C.

char *in1 = "Hello";
char in2[6] = "Hello";

In the first statement a character pointer in1 is pointing to a string literal Hello. Here you can not change the string literal. But in the second statement you are storing the string Hello in a character array in2. This can be modified to something else like in2[0] = 'h';

Deepu
  • 7,592
  • 4
  • 25
  • 47
0

The problem is that you are trying to concatenate a string to a constant string. A constant string can not be modified.

When declaring a char* test = "My string", the compiler automatically makes the variable const, because the string literal is the representation of a const char* in code.

strcat wants a char* that contains a null-terminated string and that has enough space to concatenate the second parameter. To solve that problem correct, you have to copy the first part to a buffer and then concatenate your appendix to that buffer like this:

const char* source = "Hello ";
const char* appendix = "world!";

uint32_t bufLen = strlen(source) + strLen(appendix) + 1; // length of both + null-termination
char buf[bufLen];
strcpy(buf, source);
strcat(buf, appendix);
// now buf contains your concatenated string
maxdev
  • 2,491
  • 1
  • 25
  • 50
  • Where this term *constant string* comes from ? Could give a quote from C standard ? – haccks Apr 25 '14 at 12:38
  • It's not a word from the c-standard, I just used it to describe the problem. – maxdev Apr 25 '14 at 12:43
  • `test` is not const, nor are the characters it points to. A string literal is not the representation of a `const char *`, not even close. A string literal is an *array* of non-const `char` , and it is undefined behaviour to write to it. – M.M Apr 25 '14 at 12:54
  • 2
    also `size_t` makes more sense here than `uint32_t` – M.M Apr 25 '14 at 12:56