why the output is last string from user?

后端 未结 7 1879
北海茫月
北海茫月 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:10

    Because you keep on using the same char[] str for all strings.

    Instead, you probably want to allocate a new memory block for each string. Don't forget to free them again after use.

    You can check that in the loop

    while(i<in)
    {
      printf("%p\t%s\n",arr[i],arr[i]);
      i++;
    }
    

    and you see that not only the string is the same, but its address as well.

    0 讨论(0)
  • 2020-12-22 11:10

    You need to allocate memory for each string arr[i] and then use strcpy for copy string.

    Add some code like below in your loop.

    arr[i]=malloc(strlen(str)+1);
    strcpy(arr[i],str);
    

    Also never forgot to free memory for above allocation at the end of program.

    0 讨论(0)
  • 2020-12-22 11:19

    You are storing every string in the same place, overwriting the previous string each time. Don't do that. str is a buffer, and all of the pointers in the array arr are pointing at it.

    0 讨论(0)
  • 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 <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    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.

    0 讨论(0)
  • 2020-12-22 11:21

    Because you are assigning the memory address to the array of pointer. So the address of the array will not be changed. Every array of pointer is pointing to the same address.

    When the new value is get then it will place that value in array at same address position.

    So the all values are remaining same. So avoid this you can make the str to pointer. And allocate the memory to that pointer dynamically.

    char *str;Make the allocation in while loop str=malloc(MAX);

    while(i<in)
    { str=malloc(100);//change
        scanf("%s",str);
        arr[i]=str;
      //  printf("%s\n",arr[i]);
        i++;
    }
    

    100 is an example. you can use your needed value.

    0 讨论(0)
  • 2020-12-22 11:22

    Your problem is arr[i]=str; statement.

    str is a statically allocated array, and all the arr[i] are storing the base address of it.

    As the value of str get overwritten in every call to scanf(), in your case, only the last value stored in str will be printed by accessing any arr[i].

    What you need to do

    1. Allocate memory dynamically to arr[100].
    2. use strcpy() to copy the user input from str to arr[i]

    Note: Don't forget to free() the allocated memory at last.

    0 讨论(0)
提交回复
热议问题