#arrays #c #for-loop #struct
Вопрос:
Я читаю из файла и сохраняю значения из каждой строки в структуру. Значения, которые я сохраняю, — это символ, строка и два целых числа. Затем каждая структура сохраняется в массиве структур. Я хочу распечатать каждое из этих значений, чтобы убедиться, что они были сохранены правильно, и все, кроме строк, распечатывается правильно, когда я получаю доступ к каждой структуре из массива в цикле for. Я не понимаю, почему это происходит. Чтобы проверить, я распечатал строки сразу после добавления их в структуру, которая дала ожидаемый результат. Только когда я пытаюсь получить доступ к этим строковым элементам в цикле for, я получаю неправильные выходные данные. Вот мой код:
char wordFirstLetter; struct BankAccount arrAccounts[20]; struct TransactionRequest arrTransactions[20]; int numAccounts = 0; int numTransactions = 0; int currAccountIndex = 0; int currClient = 1; while(fgets(line, sizeof(line),fp)) { // We will be getting the words on each line using strtok() //Gets the first word in the line char *word = strtok(line, " "); wordFirstLetter = word[0]; // Checks if the first letter of the line is 'a' // If it is, then we know we are setting up the account if(wordFirstLetter == 'a') { //not related } // Otherwise we are dealing with a client else { while(word != NULL) { if(word[0] == 'c') { // Move on to the next word if we see that we are // dealing with a client word = strtok(NULL, " "); } else { // Create a structure to represent the current request struct TransactionRequest transaction; // Append the client number of the client doing the transaction transaction.client = currClient; // Append the type of transaction and move to next word char *transType = word; transaction.requestType = transType; printf("This is the value of word: %sn", word); printf("%sn", transaction.requestType); word = strtok(NULL, " "); // Append the account number that will be altered and move to next word transaction.account = word[1] - '0'; word = strtok(NULL, " "); // Append the amount for the transaction and move to next word int transAmount = atoi(word); transaction.amount = transAmount; word = strtok(NULL, " "); // Append this transaction to an array containing all transactions in the file arrTransactions[numTransactions] = transaction; numTransactions ; } } // Each line represents a client, so when we are done with the // line we move to the next client currClient ; } } for(int i = 0; i lt; numTransactions; i ) { struct TransactionRequest transaction = arrTransactions[i]; printf("This is the client number: %dn", transaction.client); printf("This is the request type: %sn", transaction.requestType); printf("This is the account to be accessed: %dn", transaction.account); printf("This is the amount: %dn", transaction.amount); printf("n"); }
Это структура, которую я использую:
struct TransactionRequest { // ID if the client doing the transaction int client; // Type of transaction the client is doing char *requestType; // Account number of the account the client is dealing with int account; // Amount of money that is boing moved around int amount; };
Я что-то неправильно сделал в цикле for при распечатке этих строковых элементов? Если нет, то почему возникает эта проблема.
Комментарии:
1. Было бы полезно иметь образец файла, на котором мы могли бы его запустить?
2. @Neil Как я могу загрузить свои файлы? Это всего 2 файла.
3. @MarcoAiello, вы можете разместить непосредственно в вопросе минимальный фрагмент вашего файла, скажем, с тремя или пятью строками, достаточно, чтобы воспроизвести проблему! В дополнение к этому, что вы подразумеваете под «неверными значениями»? Не могли бы вы привести пример?
Ответ №1:
word
выходит за рамки после while
цикла, поэтому ваша структура будет содержать указатель на недопустимые данные. Даже если вы объявили word
перед циклом while, все экземпляры TransactionRequest
будут содержать самое последнее значение word
, которое, скорее всего, не соответствует предполагаемому поведению. Если вы знаете requestType
, что не будет превышать определенной длины, то вы можете использовать массив символов фиксированной длины в своей структуре. Таким образом, независимо от того, выделены ли экземпляры вашей структуры в стеке или куче, requestType
данные будут уникальными для каждого экземпляра и будут выделены/освобождены вместе со всей структурой.
#define REQUEST_TYPE_MAX_LENGTH 256 struct TransactionRequest { // ID if the client doing the transaction int client; // Type of transaction the client is doing char requestType[REQUEST_TYPE_MAX_LENGTH]; // Account number of the account the client is dealing with int account; // Amount of money that is boing moved around int amount; };
Тем не менее, потребуется значительный редизайн вашего кода. Например, вы не можете использовать присваивание для переноса данных из word
переменной в requestType
поле TranscationRequest
структуры. Вам нужно будет использовать такие функции, как strncat
ручное завершение с нулевым значением.
Хотя это не совсем связано, я также хочу отметить, что номер учетной записи в TransactionRequest
может принимать значения только от 0 до 9 (включительно), если только ваш исходный файл не содержит каких-либо странных символов ASCII. Это специально?