2016-08-19 6 views
1

EDIT

Я попытался инициализировать c, как char c[2] = {'\0'}; с теми же результатами, и изменил strncpy((char *)c, tmp, 1); к strncpy(c, tmp, 1); также с теми же результатами.C Проблемы между версиями OS X Причины Неопределенное поведение

Также был изменен strcat(tmp, (char *)c) на strcat(tmp, c) с такими же результатами.

Я также попытался использовать memset() на c с нулевыми байтами с теми же результатами. Он по-прежнему выполняет работу по 10.10.5, но выполняет также добавление ??s? к строке 10.11.6.


Я практиковал C, и решил написать текстовый синтаксический анализатор на работе. Он считывает данные из файла и выполняет операции над ним на основе различных аргументов, переданных ему. Один из вариантов заключается в том, чтобы преобразовать весь текст в файл в Pig Latin, который отлично работает на OS X 10.10.5, но я показал свою девушку дома (OS X 10.11.6) (кто помогает мне перейти от простого сценария языки Python/JS), и он начал помещать случайные байты между символами в одном и том же месте на каждом слове. Вот код и вывод на моем компьютере 10.10.

main.c

#include "parser.h" 

int main(int argc, char *argv[]) 
{ 
    if(argc < 2){err("Program Requires at Least One Argument.");} 
    if(argc > 6){err("Too many arguments.");} 

    int i = 1;  // for indexing args (don't care about arg 0) 

    /* loop over the arguments to find any parameters 
    we don't look at last argument, as it should be 
    the file name */ 
    for(i = 1; i < argc - 1; i++) { 
     if(strcmp(argv[i], "-v") == 0) {v = 1;} 
     else if(strcmp(argv[i], "-p") == 0) {p = 1;} 
     else if(strcmp(argv[i], "-c") == 0) {c = 1;} 
     else {err("Invalid Argument.");} 
    } 

    strcpy(flnm, argv[argc-1]); 

    parse(flnm); 

    return 0; 
} 

parser.c

void parse(const char *fn) 
{ 
    FILE *f = fopen(fn, "r"); 
    if(!f) {err("File does not exist.");} 

    if(v == 1) { 
     while(xfscanf(f) != 0) { 
      vwlCnt(buff); 
      printf("%s\n", buff); 
     } 

     printf("File \"%s\" contains %d vowels.\n", fn, v_cnt); 
    } 

    if(p == 1) { 
     FILE *fp = fopen("out.txt", "w+"); 
     if(!fp) {err("File write error.");} 

     while(xfscanf(f) != 0) { 
      pigLat(buff); 
      fputs(buff, fp); 
     } 

     fclose(fp); 
    } 

    if(c == 1 && v + p != 2) { 
     if(p == 1) {FILE *fp = fopen("out.txt", "r"); cat(fp);} 
     else {cat(f);} 
    } 

    fclose(f); 
} 

void pigLat(char *str) 
{ 
    int con = 0; 
    char *c[1]; 
    char *tmp = TEMP(str); 

    switch(tmp[0]) { 
     case 'a': 
     case 'A': 
      con = 0; 
      break; 
     case 'e': 
     case 'E': 
      con = 0; 
      break; 
     case 'i': 
     case 'I': 
      con = 0; 
      break; 
     case 'o': 
     case 'O': 
      con = 0; 
      break; 
     case 'u': 
     case 'U': 
      con = 0; 
      break; 
     default: 
      con = 1; 
      break; 
    } 

    if(con == 1) { 
     printf("%c\n", tmp[0]); 
     strncpy((char *)c, tmp, 1); 

     for(int i = 0; i < sizeof(tmp); i++) { 
      tmp[i] = tmp[i+1]; 
     } 

     strcat(tmp, (char *)c); 
     strcat(tmp, "ay "); 

     strcpy(buff, tmp); 
    } else {strcat(tmp, "ay "); strcpy(buff, tmp);} 

    printf("%s\n", tmp); 
} 

parser.h

#ifndef __parser_h__ 
#define __parser_h__ 

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
#include <errno.h> 

int p;    // pig latin argument; 
int v;    // vowel count argument 
int c;    // cat arg 
int v_cnt;   // vowel count 
char vwl;   // vowel char 
char flnm[64];  // file name 
char buff[32];  // file scan buffer 


void err(const char *msg);  // error function 
char *newTemp(char *str);  // creates a 32B temp pointer on heap 
int xfscanf(FILE *f);   // simple fscan 
void cat(FILE *f); 
void parse(const char *fn);  // file parsing function 
void vwlCnt(char *str);   // counts vowels in string 
void pigLat(char *str);   // pig latinize string 

#define TEMP(X) newTemp(X) 

#endif 

в поместить файл

С менее чем за одну неделю конкуренции оставленной в 2016 Рио Олимпийских играх, кажется, пустой стадион мест, чтобы украсть центр внимания от некоторых из мира наиболее украшенной athletes.So до 88% от более в Рио-де-Жанейро было продано более 6 миллионов билетов. Это меньше, чем Лондонские игры в 2012 году и Пекинские игры 2008 года, которые оба продали 96% своих билетов. Но это намного лучше, чем в Афинах 2004 года в Афинах, где было приобретено только 67% билетов на мероприятия. Присутствие было сильным для таких мероприятий, как гимнастика и спорт, в которых Бразилия должна была превзойти, например, футбол и пляжный волейбол. Тем не менее, большие полосы свободных мест можно увидеть на многих площадках, особенно на легкоатлетическом стадионе.

Выходной

ithWay esslay hantay oneay eekway белый ompetitiioncay eftlay inay hetay 0162ay ioRay Olympicay Эймс, Гей emptyay tadiumsay eatssay eemsay Otay Ебай tealingsay hetay potlighttsay awayay romfay omesay белый hetay orld'sway ostmay ecorateddday athletes.ay oSay arfay 8% 8ay ofay hetay oremay hantay 6ay millionmay otaltay icketstay avehay eenbay oldsay inay ioRay eday aneiro, Jay Olympicay organizersay aidsay ednesdayy.Way hat'sTay esslay hantay hetay ondonLay amesGay inay 0122ay anday hetay eijingBay amesGay inay 008,2ay hichway othbay oldsay 6% 9ay ofay heirtay ickets.tay ut Бей это uchmay etterbay hantay hetay 0042ay amesGay inay Athens, ay hereway ustjay 7% 6ay ofay hetay eventay icketstay ereway urchasedd.платить Посещающ ashay eenbay trongsay orfay arqueemay eventsay uchsay asay ymnasticcsgay anday portssay inay hichway razilBay ashay eenbay expecteday otay excel, ay uchsay asay occersay anday everybay olleyballl.vay до, Say argelay wathssay ofay emptyay eatssay ancay ebay eensay atay anymay enues, vay ostmay otablenay atay hetay racktay anday ieldfay tadium.say

на 10.11.6, например, seatssay заканчивается как seats?c?ay или любыми другими случайными несколько байт. Я не уверен в этом, я попытался изменить код, когда заметил это поведение, но не смог найти решение, я только сделал его хуже.

Я не включил весь файл parser.c, так как другие функции не связаны. xfscanf просто выполняет fscanf и возвращает 0, если EOF. *newTemp создает временную строку из переданной ей строки, возвращая указатель на новую копию этой строки, так что оригинал не искалечен функцией подсчета гласных (я заменяю гласные на X в этой функции).

Любая помощь или руководство были бы высоко оценены, почему это ведет себя так, как есть!

+0

И, конечно, отладчик - ваш друг. –

+0

. Какова последовательность комментариев от Марка, почему 'c' является 1-элементным массивом указателя на' char'? Что такое 'c' в этом коде? –

+0

@JohnBode Поскольку длина слова неизвестна, так как все слова имеют разную длину, я должен использовать strcat для добавления символа в конец строки, и для использования strcat вам нужно использовать строковый литерал для добавления , Таким образом, c - массив символов, чтобы использовать его при добавлении через strcat. Если char не может быть typecasted все равно ... –

ответ

0

Проблема, по-видимому, была результатом неправильной синхронизации Google Диска после внесения изменений, предложенных пользователями в комментариях. Код теперь работает, используя эти изменения:


реорганизованного pigLat использовать While-Loop, а не для цикла

int i = 0; 
    while(tmp[i] != '\0') { 
     tmp[i] = tmp[i+1]; 
     i++; 
    } 

гарантирует, что нулевые байты не в конечном итоге перемещаются туда, где они не должны перемещаться, а sizeof (tmp) не собирается возвращать фактический размер, только 32B как определено

Initialized с

char c[2] = {'\0'}; 

Программа теперь работает как задумано.

+0

, это все еще неправильно. утверждение: 'sizeof (tmp)' возвращает размер указателя: 'tmp', а не количество байтов в строке. Чтобы получить количество байтов в строке, используйте 'strlen (tmp)' – user3629249