Странный вывод всегда происходит на MacOS, но не на Ubuntu - PullRequest
0 голосов
/ 25 мая 2018

Я могу заставить эту программу на C работать должным образом в Ubuntu, но на Mac она всегда дает мне какой-то странный вывод в первой строке матрицы.

Когда я пытаюсь напечатать temp[0][k], это портит всю строку!(Вам нужен файл file.txt для запуска кода)

#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

int main (void)
{
    int fd, sz;
    int size; //the nuber of bytes of the file
    int index = 0;
    int j, m, k, i = 0;
    int count, tot = 0;
    int plain_counter = 0;
    int encoded_counter = 0;

    struct stat st;
    stat("file_input.txt", &st);
    size = st.st_size;

    char c[size];
    fd = open("file_input.txt", O_RDONLY);
    if (fd < 0) { perror("r1"); exit(1); }

    sz = read(fd, c, size);
    printf("called read(%d, c, %i).  returned that" " %d bytes  were read.\n", fd, size, sz);
    c[sz] = '\0';
    printf("Those bytes are as follows: \n%s\n", c);

    for (k = 0; k < size; k++)
    {
        if (c[k] == '\n')
        {
            index++; //countin how many times the \n appear in the file
        }
    }

    char temp[index][1024]; //array to save modifived lines
    char plain[index][512]; //array to save plain lines
    char encoded[index][512]; //array to save encoded lines

    //Bring the string from C[] to temp[][] omitting < >
    for(j = 0 ; j < index; j++)
    {
        //printf("%i\n", j);
        while(c[i] != '\n')
        {
            //printf("j = %i , k = %i  ", j, k);
            if(c[i] != '<' && c[i] != '>')
            {
                temp[j][k] = c[i];
                //printf("%c", temp[j][k]); //if i print temp here it's perfect
                k++;
            }
            i++;
        }
        printf("temp[%i][%i] = %c\n", j, k, temp[j][k]);
        temp[j][k] = '\n';
        tot += k; 
        k = 0;
        i++;
    }

    temp[j][tot + 1] = '\0';

    //printf("0 0 = %c\n", temp[0][0]);

    i = 0;
    j = 0;
    k = 0;

    //i print the temp array to check if it is well made
    while(j < index)
    {
        printf("j = %i, k = %i\n", j, k);
        while(temp[j][k] != '\n')
        {
            printf("%c", temp[j][k]); //the problem occurs here, in temp[0][k]!!
            k++;
        }
        printf("\n");

        k = 0;
        j++;
    }
    printf("\n");

    //saving the plain text into te plain array and the encoded text into te encoded array
    //it works but the first line is a mess (ONLY ON MACOS)
    for ( j = 0 ; j < index; j++)
    {
        count = 0;
        i = 0;
        k = 0;
        m = 0;
        while(temp[j][i] != '\n'){  
            if(temp[j][i] != ';')
            {
                if (count == 0)
                {
                    plain[j][k] = temp[j][i];
                    printf("%c", plain[j][k]);
                    k++;
                    plain_counter++;
                }else{
                    encoded[j][m] = temp[j][i];
                    printf("%c", encoded[j][m]);
                    m++;
                    encoded_counter++;

                }
            }
            else if(temp[j][i] == ';')
            {
                printf("\n");
                count = 1;          
            }
        i++;
        }
        printf("\n");
    }
    plain[j][plain_counter + 1] = '\0';
    encoded[j][encoded_counter + 1] = '\0';
    return 0;
}

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Вы никогда не устанавливаете свои индексы на 0!

Мой компилятор выдает предупреждение в строке 37:

warning: variable index is uninitialized when used here
    index++

Позже после этого цикла:

for (k = 0; k < size; k++)
{
    if (c[k] == '\n')
    {
        index++;
    }
}

k имеет значение size.Но вы, тем не менее, используете его, как если бы он был 0. Он работает для следующей строки, потому что вы сбрасываете его в 0 в конце цикла.

Конечно, как показано Крисом, вам следует зарезервировать некоторое место для завершающего нуляв позиции sz:

char c[size + 1];

Последнее, но не менее важное: если ваш тестовый файл не заканчивается новой строкой (не все редакторы добавляют его в последнюю строку), ваше значение index будет отключеноодним ...

Может быть другим ...

Что вы должны были извлечь из этого:

  • всегда инициализировать автоматические переменные
  • всегда проверяйте значения переменных в начале цикла
  • используйте отладчик для управления значениями во время выполнения

Мои советы, чтобы идти дальше:

  • используйте fgets для чтения ввода по строкам (гораздо более надежный, чем подсчет '\ n', какой бы ни была последняя строка)
  • напишите общую структуру программы в псевдокоде, прежде чем начинать код
  • добавьте комментарии, объясняющие, что происходит.Если при написании кода это выглядит бесполезно, но очень помогает, когда вы читаете его несколько недель спустя
0 голосов
/ 25 мая 2018

Проблема в том, что, принимая во внимание, что read не добавляет символ NUL для завершения строки, и вы добавляете его самостоятельно, вы не предоставляете массиву достаточно места для храненияЭто.Поэтому вам просто нужно увеличить размер при создании массива следующим образом:

char c[size+1];

Просто для полноты, вам также следует проверить возвращаемое значение read, так как оно может быть -1, если естьошибка.

В дальнейшем обнаружил еще пару проблем.У вас есть эта строка:

temp[j][tot + 1] = '\0';

После этого идет цикл

for(j = 0 ; j < index; j++)

Как только цикл завершится, j выйдет за пределы temp.И действительно, эта строка должна быть внутри цикла, поскольку вы хотите добавить \0 к каждой строке в temp.Таким образом, вы должны удалить его и где у вас есть эта строка:

    temp[j][k] = '\n';

Добавить эту строку, чтобы завершить строку.

    temp[j][k+1] = '\0';

А что касается k, я не вижулюбой признак того, что он установлен в 0 перед этим циклом.Вы только сбрасываете его на 0 в конце, чтобы первый раз около k мог содержать любое значение.Переместите k=0, чтобы быть первым, что происходит в цикле.

Могут быть и другие подобные проблемы - вот где отладка вашего кода с использованием valgrind будет действительно хорошей идеей, поскольку она скажет вам, где этивиды ошибок происходят.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...