1

So I'm writing a program that will loop forever, accepting string inputs until the user just presses enter with no string (along the way, I'm tracking the longest/shortest strings entered). I have this loop:

char stringIn[1000] = {'\0'};
while(1)  {
    scanf("%[^\n]s", stringIn);
    if(stringIn[0] == '\0') {
        break;
    }

    if(strlen(stringIn) > strlen(longString)) {
        longString == stringIn;
    } else if (strlen(stringIn) < strlen(shortString))  {
        shortString == stringIn;
    }
    i++;
}

Currently this just loops forever. I'm still really new to C, but to me this looks like it should've worked.

9
  • 2
    longString == stringIn does nothing. If it did make an assignment, it would be assigning longString to the same address every time and get overwritten on the next read. If you want to make a copy of the input string, use strcpy or strncpy or similar. Commented Sep 29, 2017 at 15:30
  • nit: it doesn't "do nothing", it checks if longString is equal to stringIn and evaluates to 0 or non-zero, but has no effect on the outcome of the program. Although most likely the compiler will optimize it away and it will actually do nothing. Commented Sep 29, 2017 at 15:32
  • 4
    The use of scanf is also incorrect. Use fgets instead. Commented Sep 29, 2017 at 15:36
  • try this Commented Sep 29, 2017 at 15:47
  • How does scanf accept RegEx??? I can't understand it! Commented Sep 29, 2017 at 16:02

1 Answer 1

2

Points to note:

  1. You probably mistook the == operator for =, which is assignment. Even so, it wouldn't work because here it would only copy addresses of buffers (which get overwritten) (actually in my code it would throw a compile time errors). For copying strings you wanna use strcpy.
  2. scanf is pretty vulnerable to buffer overflows and leaves the delimiter in the buffer. fgets is a much better choice for reading lines as it takes a buffer length as argument (check this out).
  3. scanf fills a number of items in it's list until characters matching the format string are read. If no chars match, then it doesn't fill stringIn, and hence doesn't append a '\0' at the end, and that's why your code never goes to break;. Instead we can use the return value, which is the number of items of the list that it fills (see here).

Anyway, here is code that does what you want:

int main() {
    char stringIn[1000] = "";
    char longString[2000] = "", shortString[2000] = "";
    int read, firstFlag = 0;
    while(1)  {
        read = scanf("%[^\n]", stringIn);
        if (read == 0) {
            break;
        }
        // to consume the '\n' left by scanf in the buffer
        getchar();

        if (!firstFlag || strlen(stringIn) > strlen(longString)) {
            strcpy(longString, stringIn);
        } 
        if (!firstFlag || strlen(stringIn) < strlen(shortString))  {
            strcpy(shortString, stringIn);
        }
        firstFlag = 1;
    }    

    printf("%s, %s\n", longString, shortString);
    return 0;
}

UPDATE: Edited according to Jonathan Leffler's comment above, correcting the use of the scanset.

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

7 Comments

strlen(stringIn) < strlen(shortString) never become true.
@BLUEPIXY Thanks, that totally got away from me. Fixed.
scanf takes \n as input when the user input return key assuming that he has entered empty string, so it contains that and when user check for str[0] it doesn't contain the null terminator instead it contains the \n.
The first entry should be copied to both longString and shortString.
@BLUEPIXY Right you are again, thanks. (I'm new at this).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.