2017-05-02 6 views
-1

Ich habe ein Programm, das eine unbekannte Anzahl von Zeichenfolgen von einem Benutzer annehmen soll. Es sollte überprüfen und sehen, ob eine Zeichenfolge bereits eingegeben wurde, so dass es keine Duplikate im dynamischen Array geben wird.Wenn Anweisung nicht nullptr

Das Problem ist, dass ich das Programm nicht erkennen kann, wenn ein Array-Steckplatz nichts enthält. Ich habe sowohl NULL als auch NULLPTR verwendet und keiner funktioniert. Was mehr ist, obwohl ich das Array noch nicht vollständig initialisiert habe, ist immer noch etwas an dem Ort.

#include "string.h" 
#include "stdio.h" 
#include "stdlib.h" 
#include "new" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    //Variables 
    int i=0,end=0,requiresSize=1; 
    char ** temp; 
    char item[256]="a"; 
    char ** requires; 

    //Requires is initialized as an array, but the individiual slots are not 
    requires = new char * [requiresSize]; 


    while(strcmp(item,"q-")){ 
     end=0; 
     printf("Enter h- for help.\nEnter q- to quit.\n"); 
     printf("Please enter a string\n"); 
     gets_s(item); 
     printf("%s\n",item); 
     if(!strcmp(item,"h-")){ 
      printf("Enter a string to add to the list.\nEnter p- to print the list.\n"); 
      end=1; 
     } 
     if(!strcmp(item,"q-")){ 
      break; 
     } 
     if(!strcmp(item,"p-")){ 
      if(requires[0]!=nullptr){ 
       for(int j=0;j<requiresSize;j++){ 
        printf("%d. %s\n",j,&requires[j]); 
       } 
      } 
      end=1; 
     } 
     while(end==0){ 
      //if search index is larger than size of the array,reallocate the array 
      if(i>= requiresSize){ 
       temp = new char * [requiresSize*2]; 
       //Initialize each element in temp 
       for(int j=0;j<requiresSize*2;j++){ 
        temp[j]= new char[256]; 
       } 
       for(int j =0;j<requiresSize;j++){ 
        //for each element in requires, copy that element to temp 
        strncpy_s(temp[j],_TRUNCATE,requires[j],_TRUNCATE); 
       } 
       delete *requires; 
       requires = temp; 
       requiresSize = requiresSize *2;   
      } 
      //if the index at requires is not empty, check to see if it is the same as given item 
      if(requires[i]!= nullptr){//This should be returning false and preventing the nested if from running, but doesn't 
       if(!strcmp(item, requires[i])){//runtime error occurs here from trying to access requires[i] 
        //if they are the same, break out of the loop, item is already included 
        break; 
       }else{ 
        //otherwise, increase the index and check again (continue loop) 
        i++; 
        break; 
       } 
      }else{ 
       //if the index is empty, add the item to the list and break out of loop 
       requires[i]= new char [256]; 
       strncpy_s(requires[i],_TRUNCATE,item,_TRUNCATE); 
       break; 
      } 

     } 
    } 
    delete *temp; 
    delete requires; 
    return 0; 
} 

ich kann nicht herausfinden, was ich bin fehlt oder an der falschen Stelle setzen

+0

Welches Buch durch alle Mitglieder nach iterieren lesen Sie?Der Grund, warum ich frage, ist, dass Leute, die Bücher lesen, besseren Code zu schreiben scheinen. Sie verwenden viel zu viele C-Funktionen, wenn es geeignetere C++ - Alternativen gibt, und ** ein Teil Ihres Codes ruft undefiniertes Verhalten auf ** (zB 'char ** temp;' ... 'delete * temp;' wie dort ist keine Voraussetzung, dass 'temp' irgend etwas vernünftiges enthält,' erfordert = neues Zeichen * [requiresize]; '...' delete requires; 'und ähnlich' requires [i] = new char [256]; '...' delete * benötigt; 'benutze 'löschen' fälschlicherweise, wo' löschen [] 'verwendet werden soll ... – Sebivor

Antwort

2
requires = new char * [requiresSize]; 

Dadurch wird eine neue Reihe von Zeiger-to-char default initialization verwenden. Default-Initialisierung eines Arrays führt zur Standard-Initialisierung seiner Elemente. Bei Nicht-Klassen- und Nicht-Array-Typen (z. B. Zeigern) führt die Standardinitialisierung zu nichts. Der Wert jedes Elements ist daher nicht spezifiziert und nicht notwendigerweise gleich nullptr.

Deshalb ist Ihre if Bedingung nicht immer erfolgreich. Es ist nicht so, dass es nullptr Werte nicht übereinstimmen, es ist, dass einige der Werte, die Sie testen, nicht gleich nullptr sind, weil nichts sie jemals auf nullptr gesetzt hat.

Andernfalls wird nichts unternommen: Die Objekte mit automatischer Speicherdauer (und deren Unterobjekte) werden initialisiert, um die Werte zu bestimmen.

Sie können value initialization ausführen, indem Sie () nach der Dimension hinzufügen. Value-Initialisierung eines Arrays verursacht Wert-Initialisierung von jedem Array-Element. Für Nicht-Klasse und nicht-Array-Typen, wert Initialisierung hat die gleiche Wirkung wie Zuordnung von Null, die den Inhalt jedes Elements zu nullptr für ein Array von Zeigern initialisiert wird:

requires = new char * [requiresSize](); 

andernfalls die Objekt wird null-initialisiert.

Es gibt jedoch keinen Grund, sich mit Zeigerarrays zu beschäftigen. Verwenden Sie einen Standardbibliothekscontainer wie .

0

Den Inhalt von etwas zu betrachten, das nicht initialisiert wird, ist schlecht, weil Sie nicht wissen, was darin ist. Also die Tatsache, dass Ihr Array Zeug enthält, obwohl Sie es nicht initialisiert haben, ist kein Problem, das Problem ist, dass Sie versuchen, auf dieses Zeug zuzugreifen.

Immer initialisieren Sie Ihre Variablen auf einen Standardwert, nachdem Sie sie erstellen, dann arbeiten Sie mit ihnen.

Zweitens, kann ich vorschlagen, dass Sie std::string und std::vector verwenden? Mit std::vector können Sie:

myVector.push_back("Whatever"); 
myVector.at(0); // this will return an out of reach exception if it doesn't exist 

std :: vector wird wachsen, wie Sie es verwenden, und Sie können mit

for (int i = 0; i < myVector.size(); i++) 
{ 
// Do stuff myVector.at(i); 
}