2012-04-14 8 views
0

Ok, also habe ich den folgenden C-CodePrintf verändert irgendwie etwas?

#include <cstdio> 
#include <cstring> 

// funkcija za mnozenje na dva 8-bitni broja (vo RC format) so Butov algoritam 
// vlez: a[] - mnozenik, b[] - mnozitel 
// izlez: proizvod[] - proizvodot (mnozenik * mnozitel) 


void shiftRight(char niza[]) 
{ 
    char out[100]; 
    strncpy(out, niza, 1); 
    strcat(out, niza); 
    out[17]='\0'; 
    strcpy(niza, out); 
} 


void add(char opa[], char opb[]) 
{ 
    char rez[100]; 
    strcpy(rez, opa); 
    char carry='0'; 
    int i=16; 
    while(i>=0) 
    { 
     int car=carry-'0'; 
     int currbita=opa[i]-'0'; 
     int currbitb=opb[i]-'0'; 
     rez[i]=((car+currbita+currbitb)%2)+'0'; 
     if(car+currbita+currbitb>=2) 
     { 
      carry='1'; 
     } 
     else 
      carry='0'; 
     i--; 
    } 
    strcpy(opa, rez); 
} 

void vtorKomplement(char in[], char out[]) 
{ 
    strcpy(out, in); 
    for(int i=0; i<8; i++) 
    { 
     if(out[i]=='0') 
      out[i]='1'; 
     else 
      out[i]='0'; 
    } 
    int i=7; 
    char carry='1'; 
    while(carry!='0') 
    { 
     int car=carry-'0'; 
     int currbit=out[i]-'0'; 
     if(car+currbit>=2) 
     { 
      carry='1'; 
     } 
     else 
      carry='0'; 
     out[i]=((car+currbit)%2)+'0'; 
     i--; 
    } 
} 

void mnozenjeButov(char a[], char b[], char proizvod[]) { 
    int i; 
    char rez[100]; 
    char A[100]; 
    char S[100]; 
    char P[100]; 
    strcpy(A, a); 
    strcat(A, "000000000"); 
    vtorKomplement(a, S); 
    for(i=8; i<17; i++) 
    { 
     S[i]='0'; 
    } 
    S[17]='\0'; 
    strcpy(P, "00000000"); 
    strcat(P, b); 
    strcat(P, "0"); 
    for(int i=0; i<8; i++) 
    { 
     if(P[15]=='0'&& P[16]=='1') 
     { 
      add(P, A); 
     } 
     else if(P[15]=='1' && P[16]=='0') 
     { 
      printf("Before add P: %s\n", P); 
      add(P, S); 
     } 
     shiftRight(P); 
     printf("Shifted P: %s\n", P); 
    } 
    for(int i=8; i<17; i++) 
    { 
     proizvod[i-8]=P[i]; 
    } 
    proizvod[8]='\0'; 
} 

int main() { 
    int success = 1; 

    char a[100]; 
    char b[100]; 
    char proizvod[100]; 
    char w_proizvod[100]; 

    // TEST 1 
    strcpy(a, "00010011"); 
    strcpy(b, "00000101"); 
    strcpy(w_proizvod, "01011111"); 
    mnozenjeButov(a, b, proizvod); 
    printf("TEST 1: %s, %s\n", a, b); 
    printf(" Tocen odgovor: %s\n", w_proizvod); 
    printf(" Vas odgovor:  %s\n", proizvod); 

    if (strcmp(proizvod, w_proizvod) == 0) { 
     printf("Vasata programa dava tocen rezultat :-)\n\n"); 
    } else { 
     printf("Vasata programa dava netocen rezultat!\n\n"); 
     success = 0; 
    } 

    if (success == 1) { 
     printf("Vasata programa gi pomina testovite uspesno!\n"); 
    } else { 
     printf("Nekoi od testovite bea neuspesni.\n"); 
    } 

    return 0; 
} 

alles schön und gut, aber etwas seltsam passiert, wenn ich danach printf("Before add P: %s\n", P); und/oder die printf entfernen. Dann ändert sich die Ausgabe irgendwie, und einige Zeichen, die nicht da sein sollten ... Ich habe versucht, zu debuggen, aber dann bekomme ich die normale Ausgabe. Ich habe auch versucht, auf einer anderen Maschine zu testen, und ich bekomme auch die komischen Charaktere dort. Ich habe mir die letzte Stunde den Kopf gestoßen, kann mir jemand sagen, wo ich falsch liege? Ich verwende Codeblocks mit Mingw GCC-Compiler.

Update: Jens Gustedts Lösung hat funktioniert.

+0

kann es nicht mit Codelite reproduzieren - debug/release mit/ohne die Linie das gleiche Ergebnis – Ulterior

+8

Beitrag a ** ** minimal kompletter Beispiel-Code! Es ist ein großer Aufwand für uns, dies auf die relevanten Teile zu reduzieren. Außerdem bin ich nicht überrascht, dass dieser Code Probleme hat. Es ist C++ nur in Namen - Sie nutzen keinen Vorteil der Sprache und verwenden Low-Level-Operationen. –

+1

Nicht sicher, ob das verwandt ist, aber ich mag die 'for (int i = 8; i <17; i ++)' Bits nicht. Ich meine, der Rest ist alles Vielfache von 8, aber 'i <17 'scheint zu weit zu gehen. –

Antwort

2

Es ist ein konzeptioneller Fehler in diesen beiden Zeilen:

strncpy(out, niza, 1); 
strcat(out, niza); 

strncpy hier nur Kopien genau ein Zeichen. Insbesondere ist out[0] gleich niza[0] und out[1] ist was auch immer dort zuvor gewesen ist. Ihre strcat schreibt dann niza an die nächste Position, wo ein 0-Zeichen gefunden wird, was zu katastrophalen Ergebnissen führen kann. (Der Mann Seite für strncpy sagt so gut.)

der Lage sein strcpy danach zu tun, dann würden Sie wahrscheinlich eine '\0' dort platzieren müssen. Aber es gibt eine viel einfachere Lösung:

out[0] = niza[0]; 
strcpy(out + 1, niza); 
+0

Wenn 'strncpy' die Antwort ist, fragen Sie wahrscheinlich die falsche Frage. http://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not-safer-strcpy.html –

+0

@KeithThompson das komische Ding war, es funktionierte gut, wenn ich Sachen ausdruckte, aber versäumte es, wenn ich nicht tat. – FREEZX

+0

@FREEZX, wenn Sie außerhalb der Grenzen auf Ihren Stack schreiben, kann alles passieren. Und für solche Fälle, wenn Sie nur wenig Änderungen am Stack-Layout Ihrer Variablen haben, können scheinbar große Änderungen im Verhalten auftreten. –