why the output is last string from user?

后端 未结 7 1933
北海茫月
北海茫月 2020-12-22 10:53
#include
#include
int main()
{
    int in,i,j;
    char *arr[100],str[14];
    scanf(\"%d\",&in);
    i=0;
    while(i

        
7条回答
  •  臣服心动
    2020-12-22 11:20

    In addition to the other responses, there are a few alternative ways to approach reading string input that you can use to simplify the what you need to keep track of in the program. As others suggested, instead of declaring arr as char *arr[100], go ahead and declare it as a pointer-to-pointer-to-char.

    char **arr = NULL;
    

    This allows you to allocate an array of character pointers. You can choose to allocate with malloc or you can choose to allocate and initialize all pointers to zero/NULL simply by using calloc instead.

    arr = calloc (100, sizeof *arr);
    

    By using calloc, this allows later iteration over only those pointers that contain strings. This further eliminates having to ask for the number of strings to enter (or keep track of how many were entered).

    After you have allocated your pointers, you need to allocate space to hold each string. While there is nothing wrong with another call to malloc (or calloc) and then a call to strcpy (or strncpy), you can do both at once with the function strdup provided in string.h. The only thing to be aware of with strdup is that it is allocating memory for you. Therefore, you are responsible for freeing that memory when no longer needed.

    Putting the pieces together, as well as the information from the comment regarding your scanf string, you can implement your string collection as follows. Note You simply enter as many strings as you like (up to the 100 pointers initially allocated), then press [enter] on a blank line when you are done:

    #include 
    #include 
    #include 
    
    int main ()
    {
        int i = 0;                              /* always initialize your variables */
        char **arr = NULL;
        char str[14] = { 0 };
    
        arr = calloc (100, sizeof *arr);        /* create 100 pointers to char*     */
    
        printf ("\nEnter strings ( [enter] alone when done )\n\n");
    
        while (printf (" input: ") && scanf ("%[^\n]%*c", str) >= 1)
            arr[i++] = strdup (str);            /* strdup allocates and copies  */
    
        printf ("\nThe strings entered were:\n\n");
        i = 0;                                  /* print the array              */
        while (arr[i]) {
            printf (" arr[%2d]: %s\n", i, arr[i]);
            i++;
        }
    
        i = 0;                                  /* free memory allocated        */
        while (arr[i])
            free (arr[i++]);
        if (arr)
            free (arr);
    
        return 0;
    }
    

    output:

    $ ./bin/str_array
    
    Enter strings ( [enter] alone when done )
    
     input: string 1
     input: string 2
     input: string 3
     input:
    
    The strings entered were:
    
     arr[ 0]: string 1
     arr[ 1]: string 2
     arr[ 2]: string 3
    

    There are many, many ways to approach this problem. Compare all the answers and add the different approaches to your collection. There are always places where one will have benefits over the other, and vice-versa. Note, in the above code you should check whether any allocation with calloc, malloc, or strdup succeeds and handle the error if it fails. You should also check when you get to the 99th sting entered and reallocate the number of pointers as needed. Those checks are omitted for clarity.

    valgrind memory useage summary

    Get in the habit of always verifying your memory usage with valgrind. It will point out any place where you have allocated memory that you have failed to free. While the memory in a short bit of code like this will be freed on exit, in longer code, failing to keep track of the memory you allocate can lead to significant amounts of memory in use by your program after it is no longer needed (memory leaks). A quick check with valgrind will disclose any problems or confirm all is well:

    ==28677== HEAP SUMMARY:
    ==28677==     in use at exit: 0 bytes in 0 blocks
    ==28677==   total heap usage: 4 allocs, 4 frees, 827 bytes allocated
    ==28677==
    ==28677== All heap blocks were freed -- no leaks are possible
    ==28677==
    ==28677== For counts of detected and suppressed errors, rerun with: -v
    ==28677== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
    

    Let me know if you have any questions.

提交回复
热议问题