Thread: Why is the first array getting printed twice when both arrays are ordered like this?

  1. #1
    Registered User
    Join Date
    Mar 2023
    Posts
    33

    Why is the first array getting printed twice when both arrays are ordered like this?

    Created a program that converts one string to upper case, then another string to lower case. For some reason, if in the main function, i declare the first array on top of the second, the loop prints the whole array twice. It doesn't matter which array and function goes first, i've tested it out with both:

    Code:
    #include<stdio.h>
    #include<ctype.h>
    //first array is labeled one, second array is
    //labeled two
    void upperString(char one[])
    {
      int z = 0;
    
      while(one[z])
      {
        one[z] = toupper(one[z]);
        z++;
      }
    
      printf("%s\n", one);
    }
    
    void lowerString(char two[])
    {
      int x = 0;
    
      while(two[x])
      {
        two[x] = tolower(two[x]);
        x++;
      }
    
      printf("%s\n", two);
    }
    
    int main()
    {
      char one[4] = {'a', 'b', 'c', 'd'};
    
      char two[4] = {'A', 'B', 'C', 'D'};
    
      upperString(one);
    
      lowerString(two);
    }
    Output:

    ABCDABCD
    abcd

    The fix is simple, you execute the first function directly after you declare the first array:

    Code:
    int main()
    {
      char one[4] = {'a', 'b', 'c', 'd'};
      
      upperString(one);
    
      char two[4] = {'A', 'B', 'C', 'D'};
    
      lowerString(two);
    
    }
    Output with change:

    ABCD
    abcd

    ...but it doesn't make any sense to me why the ordering matters, nowhere in the code am I telling either of the loops to print out the string twice in the above example. I'm really curious about why the ordering DOES matter.

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    You need to pass the array size to the functions

    In other words,
    Code:
    while(one[z])
    Is not valid/safe code.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,652
    Neither array is a proper C string.

    Try with these.
    Code:
    char one[5] = {'a', 'b', 'c', 'd', '\0' };
    char one[5] = {'a', 'b', 'c', 'd' }; // \0 for free
    char one[] = "abcd"; // \0 for free, no counting, less editing
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    Is it possible that as Salem said the first string isn't terminated so the first while loop is operating on both strings?? IE the second string is right after the first one in memory so effectively the first function is passed abcdABCD......................./0 where the rest isn't printed as they aren't valid characters?? Hence why the op's second version appears to behave as expected because the second string hasn't been created when the first string is printed.

  5. #5
    Registered User
    Join Date
    Mar 2023
    Posts
    33
    Quote Originally Posted by cooper1200 View Post
    Is it possible that as Salem said the first string isn't terminated so the first while loop is operating on both strings?? IE the second string is right after the first one in memory so effectively the first function is passed abcdABCD......................./0 where the rest isn't printed as they aren't valid characters?? Hence why the op's second version appears to behave as expected because the second string hasn't been created when the first string is printed.
    Those were my initial thoughts, Salem had the correct answer. All arrays need to at least have the additional space for the null pointer for them to function properly. I've tested both of these and they both make the program run in the way I intended:

    Code:
    int main()
    {
      char one[5] = {'a', 'b', 'c', 'd'};
     
      char two[5] = {'A', 'B', 'C', 'D'};
     
      upperString(one);
     
      lowerString(two);
    }
    Code:
    int main()
    {
      char one[5] = {'a', 'b', 'c', 'd', '\0'};
     
      char two[5] = {'A', 'B', 'C', 'D','\0'};
     
      upperString(one);
     
      lowerString(two);
    }
    Idk why I thought doing it the way of the answer above was acceptable, i think it's maybe because gcc normally complains when you have a mis-matched number of elements reserved with the number of slots you declare, so I thought it was just putting the null terminator in there for me this whole time.

    Quote Originally Posted by stahta01 View Post
    You need to pass the array size to the functions

    In other words,
    Code:
    while(one[z])
    Is not valid/safe code.

    Tim S.
    That's fine for you to point that out and all, but I can't do anything with that information. I appreciate your interest.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating an ordered array from binary search tree
    By Donald Salguero in forum C Programming
    Replies: 3
    Last Post: 12-11-2012, 12:31 PM
  2. array being printed incorrectly
    By amissot in forum C Programming
    Replies: 4
    Last Post: 12-29-2011, 05:10 AM
  3. avoid duplicates in an ordered array
    By baffleddreams in forum C Programming
    Replies: 1
    Last Post: 09-19-2010, 01:53 AM
  4. Replies: 8
    Last Post: 11-12-2008, 11:25 AM

Tags for this Thread