Почему я получаю лишний символ при попытке записи в файл?

#c #posix

Вопрос:

Предполагается, что это переворачивает прописные и строчные буквы, но это не переворачивание, а просто добавление случайных символов.

 
    int  in = open(argv[1], O_RDONLY);
    int out = open(argv[2], O_CREAT | O_WRONLY, 0624);
    char buff[65];
      buff[64] = '';
  
    if(argc < 2){
        printf("Not enough arguments");
        return 1;
    }
    else if(argv[1] == 0 || argv[2] == 0){
        printf("No file");
        return 1;
    }
int i = read(in,buff,64);
        
for (i = 0; buff[i]!=''; i  ) {
    if(buff[i] >= 'a' amp;amp; buff[i] <= 'z') {
      printf("%d", buff[i]-32);
    } else if (buff[i] >= 'A' amp;amp; buff[i] <= 'Z') {
        printf("%d", buff[i] 32);    
    } else {
       printf("%d", buff[i]);
      }
    }
    
    write(out, buff, 64);
    close(in);
    close(out);
    return 0;
}
 

Как мне заставить его прочитать персонажа и перевернуть без дополнительных дополнений?

Комментарии:

1. вы должны на самом деле изменить buff , прежде чем записывать его в файл, если вам нужно что-то, кроме прямой копии

2. if(buff[i] >= 'a' amp;amp; buff[i] <= 'z') и ваш аналогичный код полностью непереносим и не гарантирует, что он будет работать. Вы действительно хотите использовать isupper() / islower() и toupper() / tolower() вместо этого.

Ответ №1:

Если ваш входной файл не содержит '' последнего символа, ваше состояние buff[i]!='' зависит от случайного содержимого.

Измените эти строки:

 char buff[65];
      buff[64] = '';
 

к этой строке:

 char buff[65] = { 0 };
 

Однако read() сообщает вам количество прочитанных байтов. Вы можете использовать это значение, чтобы отметить конец:

 int n = read(in,buff,64);
        
for (i = 0; i < n; i  ) {
    /* ... */
}

write(out, buff, n);
 

Комментарии:

1. Все это правильно, на самом деле мало что даст, так как никогда не buff изменяется. он скопирует файл размером менее 65 байт

Ответ №2:

Напишите функцию, которая считывает строку до некоторого максимального размера; отделите логику чтения файла от другой обработки,

 int readline(int fh, char* buff, int maxsize) {
    int rc = read(fh,buff,maxsize);
    if( rc < 0 ) {
        printf("read error, %dn",rc);
        return rc;
    }
    return rc;
}
 

Напишите функцию, которая записывает преобразованный буфер, разделите логику записи файла и другой обработки,

 int writeline(int fh, char* buff, int len) {
    int wc = write(fh, buff, len);
    return wc;  
}
 

Напишите функцию, которая переворачивает регистр; отделите логику от чтения и записи файла,

 char* flipcase(char* buff, int len) {
    if(!buff || len<1) return buff;
    char* cp = buff;
    for (int ix = 0; ix<len; ix  , cp   ) {
        if( isupper(*cp) { // in [A-Z]
            // printf("%d", *cp-32); // not portable
            *cp = tolower(*cp); // modify buff[ix]
        }
        else if( islower(*cp) ) { // in [a-z]
            // printf("%d", *cp 32); // not portable
            *cp = toupper(*cp); // modify buff[ix]
        }
        // else {
        //     unchanged
        // }
        // printf("%d", *cp);
    }
    return buff;
}
 

Создайте функцию, которая обрабатывает каждую строку отдельно,

 # define MAXLINE (256) // named 'constant'

int doline(int fin, int fout) {
    char buff[MAXLINE 1] = { 0 };
    int rc = readline(fin, buff, MAXLINE);
    // check results of readline here
    flipcase(buff, rc);
    int wc = writeline(fout, buff, rc);
    // check results of writeline here
    return rc;
}
 

Здесь вы обработаете свои (argc, argv) и откроете свои файлы,

 if(argc < 3) {
    printf("Not enough arguments");
    return 1;
}
if(argv[1] == 0 || argv[2] == 0) {
    printf("No file");
    return 1;
}
int  fin = open(argv[1], O_RDONLY);
if( !fin ) {
    printf("open %s failedn",argv[1]);
    return 2;
}
int fout = open(argv[2], O_CREAT | O_WRONLY, 0624);
if( !fout ) {
    printf("open %s failedn",argv[2]);
    close(fout);
    return 2;
}

int rc = 0;
// process one line
rc = doline(fin,fout);
// or, process every line in file
for( ; rc = doline(fin,fout) >= 0; ) {
}

close(fin);
close(fh);