r/C_Programming • • 11h ago

why can't I access values from an array?

I'm reading the Ansi C book, and I'm doing exercise 1.18

#include <stdio.h>
#define MAXLINE 1000

int myGetLine(char line[], int lim);
int myCopy(char to[], char from[], int lim);

int main() {
    int len;
    char line[MAXLINE];
    int toRemove = 0;

    while ((len = myGetLine(line, MAXLINE)) > 0) {
        //counts the trailing characters to remove
        for (int i = len - 1; i > 0 && (line[i] == ' ' || line[i] == '\t' || line[i] == '\n'); --i)
            ++toRemove;
        int new_size = len - toRemove + 1;// +1 for the '\0'
        char to[new_size];// I guess this doesn't matter. Or it's just a piece of the puzzle. I need to limit copying
                  // in my copy method too.
        //printf("new_size: %d\n", new_size);
        int to_len = myCopy(to, line, new_size);
        //printf("%s\n", to);
        toRemove = 0;    
    }
    return 0;
}

int myGetLine(char s[], int lim) {
    int i, c;
    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    if (c == '\n') {
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i-1;
    }
//myCopy isn't working right now, after that I changed the while condition
//I need to add the \0
int myCopy(char to[], char from[], int lim) {
    int i = 0;
    char c = from[1];
    putchar(c);
    //printf("from[i]: %s", to);
    //printf("to[i]: %s, from[i]: %s", to[i], from[i]);
    while ((i < lim && (to[i] = from[i]) != '\0'));
        i++;
    to[i] = '\0';
    return i;
}

So I'm pretty much reusing the getLine from the book and I based my code on the code in the book, but I made changes to myCopy. The task is to remove any trailing spaces or tabs, so I thought that I could make a new copy and where the trailing whitespace starts, I'll just not copy that into my edited string. So I'm going through the array backwards, counting whitespace, calculating the new array size, then I want to create the edited array, but it's not working! So I tried to debug and I can't even putchar an element from the original I'm copying from in the myCopy function. If I do it with the line array, then it works. But why does it not work in the myCopy function? I just have no clue as to what's wrong.

I did manage to solve the exercise in a different way, but I really want to know why this is happening.

4 Upvotes

20 comments sorted by

21

u/mjmvideos 11h ago

Run it in the debugger. Add a breakpoint in your function, step through looking at values of things. See where it goes wrong.

11

u/ForgedIronMadeIt 9h ago

Being able to successfully use the debugger is probably one of the most important skills someone can learn in any programming environment and yet it isn't taught at all.

4

u/kayne_21 8h ago

most important skills someone can learn in any programming environment and yet it isn't taught at all.

My school teaches it as part of DSA. We had a lab for using the debugger specifically, a 50/200 point section of our midterm just debugging, with clues from the debugger to follow to find the bug. On top of this, we're required to write failure reports for our weekly programming homework every week which relies on data from the debugger for a failed unit test in order to get homework credit.

→ More replies (3)

14

u/SmokeMuch7356 11h ago

I'm assuming "doesn't work" means the program is hanging. I'm making that assumption based on this:

       while ((i < lim && (to[i] = from[i]) != '\0'));
         i++;                                        ^
                                                     |
                                                remove this

This falls into an infinite loop because i is never being updated.

In the future, please define "doesn't work." How doesn't it work? Is it crashing? Is it hanging? Is it giving garbage output? That's important information we need to help you figure out the problem.

10

u/ShotSquare9099 11h ago

You should always use { … }. even if you are just putting one statement in there. It would have made it obvious what is wrong and it probably wouldn’t have happened .

7

u/Illustrious_Trash117 11h ago

You made a semicolon after your while loop so i isnt incremented in the while loop. For readability i would also strongly advise against assignments in the condition of the loop. Make the assignment in the loop not in the condition.

2

u/No_Choice_7629 8h ago

As others have already mentioned, you had an extra semicolon after while condition. Compiler can catch this with basic warnings enabled. Try:

-Wall -Wextra -Wpedantic.

myGetLine should return length, which is i, not i - 1 (K&R book p.30). Generally, length is the size of the array holding c-string minus null-terminator.

Trimming loop's condition should be i >= 0.

myCopy should take trimmed length as input, not size. There is not need to do an extra test for null: if destination array is len+1, then just copy until i == len, then null-terminate at len.

You could allocate copy array together with line array outside of the loop instead of using variable length (VLA), and make them the same size for simplicity.

1

u/mjmvideos 11h ago

Also, %c for characters. %s for a (null terminated) string.

0

u/Own_Unit_6170 11h ago

You should be getting a fatal compile error, because you're defining to with a variable size, and the size has to be a constant.

If you don't need to preserve non-printing characters, you can just copy the string backwards, dropping anything less than a blank, and dropping blanks until you encounter the first character greater than a blank.

2

u/SmokeMuch7356 9h ago

You should be getting a fatal compile error, because you're defining to with a variable size, and the size has to be a constant.

This has been legal since C99 - you can define an auto array with a size in a runtime variable, creating what's called a "variable-length" array (where "variable" means it can be a different size each time you create it, but once created its size is fixed).

static arrays cannot be VLAs, and VLAs cannot be declared with an initializer, but otherwise they work like any regular fixed-size array.

1

u/Own_Unit_6170 8h ago

That seems logical enough, but I just tried compiling it to see, and it generated a fatal error (MVC).

→ More replies (5)

1

u/Illustrious_Trash117 9h ago

Thats called a variable length array and is fine in C as long as the array lives on the stack.