1

I am processing an input string, which consists of a process name, followed by an arbitrary amount of arguments.

I need the process name , along with all of the arguments, in one string. I thought I could use strcat in a loop, so that it cycles through all of the args and each time appends the arg to the string, but I am having problems with getting a string that in empty to begin the loop.

Can anyone help me out with some basic code?

Thanks.

EDIT: I'm posting my code for clarity. Mike's post is closest to what I have now:

    char * temp;
    strcpy(temp,"");
    for (i = 4; i < argc-1; i++) // last arg is null, so we need argc-1
    {
        strcat(temp,argv[i]);
        strcat(temp," ");
    }

ignore the 4 in my for loop for the moment (magic number, i know.) I am getting a segfault with this code. Is it because of my string assignment? I assume that is the case and hence I asked the question of how i could combine the strings.

3
  • 1
    I think you are going to need to allocate a buffer somewhere. That first strcpy into a random buffer is going to require a lot of luck to work! Commented Mar 5, 2011 at 19:42
  • If you could form that into an answer, I will give you the checkmark. Because thats all i needed, was a malloc of temp first. Thanks! Commented Mar 5, 2011 at 19:48
  • I've updated my answer. I didn't include lots of code because I think you basically know what you are doing and don't need the code written for you! Commented Mar 5, 2011 at 19:54

5 Answers 5

5

Let's say your input strings are in an array of char pointers, suggestively called argv, of length argc.

We first need to determine how much space is needed for the output:

int length = 0;
for (int i = 0; i < argc; ++i)
    length += strlen(argv[i]);

Then we allocate it, adding an extra char for the '\0' terminator:

char *output = (char*)malloc(length + 1);

Finally, the concatenation:

char *dest = output;
for (int i = 0; i < argc; ++i) {
    char *src = argv[i];
    while (*src)
        *dest++ = *src++;
}
*dest = '\0';

Note that I don't use strcat here. Reason is that this sets us up for a Schlemiel the Painter's algorithm: for each iteration, the entire output string would be scanned to find its end, resulting in quadratic running time.

Don't forget to free the output string when you're done:

free(output);

I'm a bit tired so I may be overlooking something here. A better solution, using standard library functions, is welcome. It would be convenient if strcat returned a pointer to the terminator byte in dest, but alas.

Sign up to request clarification or add additional context in comments.

2 Comments

You could also use a series of s(n)printf calls as they return the number of characters written.
This ought to be simpler than a heavyweight printf variant. But you're right, it does work.
1

You want an empty C string? Is this what you are looking for: char p[] = "";?


UPDATE

After you posted some code it is clear that you have forgotten to allocate the buffer temp. Simply run around the arguments first, counting up the length required (using strlen), and then allocate temp. Don't forget space for the zero terminator!

Comments

0

You could provide the "arbitrary amount of arguments" as one argument, ie an array/list, then do this pseudocode:

str = "";
i = 0;
while i < length of input
{
str = strcat ( str , input[i]);
i++;
}

Comments

0
    #include<stdio.h>
    #include<stdarg.h>

    int main(int argc, char** argv) { 
            // the main parameters are the same situation you described
            // calling this program with    main.exe asdf 123 fdsa, the program prints out: asdf123fdsa

            int lengths[argc];
            int sum =0;
            int i;
            for(i=1; i<argc; i++) { // starting with 1 because first arg is program-path
                    int len = strlen(argv[i]);
                    lengths[i] = len;
                    sum+=len;
            }
            char* all = malloc(sum+1);
            char* writer = all;
            for(i=1; i<argc; i++) {
                    memcpy(writer, argv[i], lengths[i]);
                    writer+=lengths[i];
            }
            *writer = '\0';
            printf("%s\n", all);

            system("pause");
            return 0;
    }

4 Comments

I think int lengths[argc]; is not standard C, is it?
@Thomas yes, it was only added in C99. A malloc(sizeof(int) * argc) would be compatible with older compilers.
This will get the job done. Doesn't it just make you love languages with real built-in dynamic length string objects!
Indeed. I am doing equally much in C as in Smalltalk but i have to say Smalltalk does this in 35 bytes of code.
0

A string in C is represented by an array of characters that is terminated by an "null" character, '\0' which has the value 0. This lets all string functions know where the end of a string is. Here's an exploration of different ways to declare an empty string, and what they mean.

The usual way of getting an empty string would be

char* emptyString = "";

However, emptyString now points to a string literal, which cannot be modified. If you then want to concatenate to an empty string in your loop, you have to declare it as an array when you initialize.

char buffer[] = "";

This gives you an array of size one. I.e. buffer[0] is 0. But you want an array to concatenate to- it has to be large enough to accomodate the strings. So if you have a string buffer of certain size, you can initialize it to be empty like so:

char buffer[256] = "";

The string at buffer is now "an empty string". What it contains, is buffer[0] is 0 and the rest of the entries of the buffer might be garbage, but those will be filled once you concatenate your other strings.

Unfortunately, the problem with C, is you can never have an "infinite" string, where you are safe to keep concatenating to, you have to know it's definite size from the start. If your array of arguments are also strings, you can find their length using strlen. This gives you the length of a string, without the null character. Once you know the lengths of all your sub-strings, you will now know how long your final buffer will be.

int totalSize; // assume this holds the size of your final concatenated string
// Allocate enough memory for the string. the +1 is for the null terminator
char* buffer = malloc(sizeof(char) * (totalSize + 1));
buffer[0] = 0; // The string is now seen as empty.

After this, you are free to concatenate your strings using strcat.

2 Comments

That's a very far from canonical way to get an empty C string.
@David Heffernan I guess I was getting ahead of myself. I added some clarifications.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.