0

I was working on an exercise in C and came across a very strange thing. The program is supposed to take input and put it into an array. (It's also supposed to check if the line is >80 characters long, but that's not implemented yet and isn't involved in the problem.) The initial problem was that each new line overwrites the previous. My attempt to fix this resulted in a bug where nothing was output.

The original function that copies a single line is:

void copy(void)
{
  int i;
  extern char line[], storage[];

  i = 0;
  while ((storage[i] = line[i]) != '\0')
    i++;
}

line contains the source string with \0 at the end. storage is where it is stored after. Each time copy is called, the new value in line overwrites the value in storage.

I tried adding another index (named curend) to copy() to track the position in storage between calls (see full sample code below), which would point to right after the previous string, and then increment that index in copy()'s while loop. After this change, copy() seemingly just stops saving anything into storage. It compiles and runs without warnings or error. Why is this happening?

/* The purpose of the program is to take an input
   of a string, check if it's >80 characters long
   and put it into storage[]. Then repeat until
   the input is EOF. And print what's in storage as 1 string */

#include <stdio.h>

#define MAXLEN  1000    // maximum length a line can be
#define REQLEN  3   // length required to pass the check
            // right not is set to 3 for testing
#define MAXSTOR 1000000

int curend = 0; // current end of the previous line
int len;    // global length
char line[MAXLEN];
char storage[MAXSTOR];

/* The issue occurs here. It seems to not write anything into storage[] at all. */
void copy(void)
{
    int i;
    extern int curend;
    extern char line[], storage[];

    i = 0;
    while ((storage[curend] = line[i]) != '\0')
        i++;
        curend++; // this line is added
    storage[curend] = '\n';
    curend++;
}

int getlines(void)
{
    int c, i;
    extern char line[];

    for (i = 0; i < MAXLEN-1
            && (c=getchar()) != EOF && c != '\n'; i++)
                line[i] = c;
    if (c == '\n' ) {
        line[i] = c;
        i++;
    }
    line[i] = '\0';
    return i;
}
int main()
{
    extern int len;
    extern char storage[];
    
    while ((len = getlines()) > 0)
        if (len > REQLEN)
            copy();
    storage[curend] = '\0';
    printf("%s", storage);
}


outis
  • 75,655
  • 22
  • 151
  • 221
peonerovv
  • 3
  • 2
  • 1
    What's this about forks? – Steve Summit Dec 22 '21 at 22:59
  • I'm having trouble understanding your last paragraph. Rather than explain what you're doing can you show us the code that uses your `copy` function? – Kevin Dec 22 '21 at 22:59
  • 5
    *when I tried to put another integer into storage instead of "i"* you're not putting `i` into `storage` to begin with. Can you show the code that works, and then the code that doesn't work? [example]. Hard for us to reason about code we can't see. – JohnFilleau Dec 22 '21 at 22:59
  • 1
    Unusual to have a `copy` function that copies between, it seems, two global variables. Is there a reason you've set it up this way – Steve Summit Dec 22 '21 at 23:01
  • 1
    Instead of showing code that works and then explaining the process of breaking it, just show the end result: code that does not work. – n. m. could be an AI Dec 22 '21 at 23:04
  • In C, a `char` is not a string. As its name suggests, it is a single character, stored as a small integer. A string of characters can be represented as an array of `char`, where the last element is 0 (since C arrays don't store their length, the end of the string must be explicitly marked). An array of strings is either a two-dimensional array of `char`, which is hardly ever a good idea, or an array of pointers to strings, usually dynamically allocated. – rici Dec 22 '21 at 23:04
  • For the pedantic only: `while ((storage[i] = line[i]) != '\0')` incorrectly stops the loop when `line[i]` is a non-two's complement -0. String copy should only stop on +0. – chux - Reinstate Monica Dec 22 '21 at 23:08
  • @chux Are you raising a serious concern, or are you just showing off? :-) – Steve Summit Dec 22 '21 at 23:19
  • @SteveSummit Just having fun with that idle curiosity. Non-2's compliment will certainly officially pass away with C2x, and, like many prior technologies, will slip silently away. – chux - Reinstate Monica Dec 22 '21 at 23:43
  • 1
    Does this answer your question? "[I am using turbo C++ and my program is producing no output](//stackoverflow.com/q/3305274/90527)". See also: "[Why is it considered a bad practice to omit curly braces?](//stackoverflow.com/q/359732/90527)". – outis Dec 24 '21 at 01:12
  • In general, an interactive debugger is your most powerful tool in cases like this, for troubleshooting unexpected behavior and crashes. Find and learn to use whatever debugger your development suite provides. – outis Dec 24 '21 at 07:59
  • [Warnings are errors](https://godbolt.org/z/EdeGfsx1v). Enable them. [Why and how](https://stackoverflow.com/questions/57842756/). – n. m. could be an AI Dec 25 '21 at 12:10
  • I'm not sure what to think of the local `extern` variable declarations. They are certainly allowed, and I see some documentary value to them, but it would be more conventional to omit those. And it would probably be better practice to avoid relying on global variables in the first place. – John Bollinger Dec 25 '21 at 12:42

0 Answers0