2016-08-19 2 views
1

EDIT

J'ai essayé d'initialiser c comme char c[2] = {'\0'}; avec les mêmes résultats, et a changé strncpy((char *)c, tmp, 1);-strncpy(c, tmp, 1); aussi avec les mêmes résultats.C Problèmes entre les versions OS X Causes Comportement non défini

Également modifié strcat(tmp, (char *)c) à strcat(tmp, c) avec les mêmes résultats. J'ai également essayé d'utiliser memset() sur c, avec des octets nuls, avec les mêmes résultats. Il fonctionne toujours comme prévu le 10.10.5, mais effectue également l'ajout de ??s? à la chaîne le 10.11.6. J'ai pratiqué du C et j'ai décidé d'écrire un analyseur de texte au travail. Il lit les données d'un fichier et effectue des opérations en fonction des différents arguments qui lui sont transmis. Une option est de faire convertir tout le texte dans un fichier à Pig Latin, qui fonctionne bien sur OS X 10.10.5, mais j'ai montré ma petite amie à la maison (OS X 10.11.6) (qui m'aide à migrer à partir de scripts faciles) Python/JS) et il a commencé à mettre des octets aléatoires entre les caractères au même endroit sur chaque mot. Voici le code et la sortie sur ma machine 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 

en placer le fichier

Avec moins d'une semaine de compétition gauche aux Jeux Olympiques de Rio 2016, les sièges vides du stade semblent voler la vedette de certains des athletes.So le plus décoré du monde jusqu'à 88% de plus Plus de 6 millions de billets ont été vendus à Rio de Janeiro, ont annoncé mercredi les organisateurs des JO. C'est moins que les Jeux de Londres en 2012 et les Jeux de Pékin en 2008, qui ont tous deux vendu 96% de leurs billets. Mais c'est beaucoup mieux que les Jeux d'Athènes en 2004, où seulement 67% des billets ont été achetés. L'adhésion a été forte pour des compétitions de renom telles que la gymnastique et le sport dans lesquelles le Brésil excellait, comme le football et le beach volley. Pourtant, de grandes surfaces de sièges vides peuvent être vues à de nombreux endroits, notamment au stade d'athlétisme.

sortie

ithWay esslay Hantay oneay eekway ofay ompetitiioncay eftlay Inay hetay 0162ay ioRay Olympicay ames, Gay emptyay tadiumsay eatssay eemsay otay ebay tealingsay hetay potlighttsay awayay romfay omesay ofay hetay orld'sway ostmay ecorateddday athletes.ay oSay arfay 8% 8ay ofay hetay oremay hantay 6ay illionmay otaltay icketstay avehay oldsay inay ioRay eday aneiro, Jay Olympicay organisersay aidsay ednesdayy.Way hat'sTay essay hasay hayay ondonLay amesGay inay 0122ay anday hetay einayay 008,2ay hichway othbay oldsay 6% 9ay jours de congé heirtay.tay ut La baie est peut-être uchmay etterbay hantay hetay 0042ay amesGay inay Athènes, ayez ici herestay 7% 6ay ofay hetay eventay icketstay ereway urchasedd.payer Attendez-vous à ashay eenbay trongsay orfay arqueemay eventsay uchsay asay ymnasticcsgay anday portssay inay hichway razilBay ashay eenbay expecteday otay excel, ay uchsay asay occersay anday eachbay olleyballl.vay jusqu'à, Say argelay wathssay ofay videay eatssay ancay ebay eayay atay anymay enues, vay ostmay otablynay atay hetay racktay Anday ieldfay tadium.say

Sur 10.11.6, par exemple, seatssay se termine comme seats?c?ay ou tout autre quelques octets aléatoires. Je ne suis pas sûr de la cause de cela, j'ai essayé de modifier du code quand j'ai remarqué le comportement mais je n'ai pas réussi à trouver une solution, je n'ai fait qu'empirer les choses.

Je n'ai pas inclus le fichier entier parser.c, car les autres fonctions ne sont pas liées. xfscanf effectue simplement fscanf et renvoie un 0 si EOF est atteint. *newTemp crée une chaîne temporaire à partir de la chaîne qui lui est transmise, renvoyant un pointeur vers une nouvelle copie de cette chaîne, afin que l'original ne soit pas mutilé par la fonction de comptage vocalique (je remplace les voyelles par X dans cette fonction).

Toute aide ou conseil serait très apprécié avec la raison pour laquelle il se comporte comme il est!

+0

Et le débogueur est votre ami, bien sûr .. –

+0

Un suivi d'un commentaire de Mark, pourquoi 'c' un tableau de 1 élément de pointeur' char'? Quel est le but de 'c' dans ce code? –

+0

@JohnBode Puisque la longueur d'un mot est inconnue, comme tous les mots ont une longueur différente, je dois utiliser strcat pour ajouter le caractère à la fin de la chaîne, et pour utiliser strcat, vous devez utiliser une chaîne littérale pour l'ajouter . Donc, c est un tableau de caractères afin de l'utiliser en ajoutant via strcat. A moins qu'un char ne puisse être typé de la même façon ... –

Répondre

0

Le problème semblait provenir de la mauvaise synchronisation de Google Drive après avoir apporté les modifications suggérées par les utilisateurs dans les commentaires. Le code fonctionne maintenant, en utilisant ces changements:


Restructuré pigLat utiliser un while plutôt que pour boucle

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

assure que des octets nuls ne finissent pas par être déplacé à l'endroit où ils ne devraient pas être déplacés, et sizeof (tmp) ne va pas retourner la taille réelle, seulement 32B comme cela est défini

Initialisé c

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

Programme de travail maintenant comme prévu.

+0

c'est toujours faux. l'instruction: 'sizeof (tmp)' renvoie la taille du pointeur: 'tmp', pas le nombre d'octets dans la chaîne. Pour obtenir le nombre d'octets dans une chaîne, utilisez 'strlen (tmp)' – user3629249