错误的控制台读取

时间:2017-11-14 08:54:30

标签: c scanf fgets

任务:将欧姆从 1 kOhm 转换为 1000欧姆等,并找到最大值和最小值。

示例:

1 kOhm

2欧姆

转换为

1000欧姆

2欧姆

但输入后才获得

1 kOhm

欧姆

输入必须带空格。程序首先从每个新行中删除1个字符。我尝试使用wscanf和其他人认为,但它对我来说并不适合。

P.S。我必须使用wchar_t

#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>

int pow(int base, int exp) {
  if (exp < 0)
    return -1;

  int result = 1;
  while (exp) {
    if (exp & 1)
      result *= base;
    exp >>= 1;
    base *= base;
  }

  return result;
}
int transformSize(wchar_t name) {

  if (name == L'h') {
    return 2;
  } else if (name == L'k') {
    return 3;
  } else if (name == L'M') {
    return 6;
  } else if (name == L'G') {
    return 9;
  } else if (name == L'T') {
    return 12;
  } else if (name == L'P') {
    return 15;
  } else if (name == L'E') {
    return 18;
  } else if (name == L'Z') {
    return 21;
  } else if (name == L'Y') {
    return 24;
  }

  return 0;
}

int main() {

  unsigned int *numbers;
  unsigned int min = 0;
  unsigned int max = 0;
  int n = 0;
  wchar_t **array;
  setlocale(LC_ALL, "");

  wprintf(L"Enter n: ");
  wscanf(L"%d", &n);

  array = malloc(n * sizeof(wchar_t *));
  numbers = malloc(n * sizeof(unsigned int *));

  wprintf(L"Enter n-elements: \n");

  for (int i = 0; i < n; i++) {
    wchar_t temp;
    array[i] = malloc(256 * sizeof(wchar_t));
    wscanf(L"%c", &temp);
    fgetws(array[i], 2560, stdin);
  }

  wprintf(L"\n\nStart array: [");

  for (int i = 0; i < n; i++) {
    wprintf(L" ");
    wprintf(L"%ls", array[i]);
    wprintf(L" ");
  }

  wprintf(L"]\n\n");

  for (int i = 0; i < n; i++) {
    int spaceIndex = 0;
    for (int j = 0; j < wcslen(array[i]); j++) {
      if (array[i][j] != ' ') {
        spaceIndex++;
      } else {
        break;
      }
    }

    wchar_t *new = malloc(sizeof(wchar_t) * spaceIndex + 1);
    wcsncpy(new, array[i], spaceIndex);
    new[n] = '\0';
    numbers[i] = wcstol(new, (wchar_t **)NULL, 10) *
                 (pow(10.0, (double)transformSize(array[i][spaceIndex + 1])));

    if (i == 0) {
      min = numbers[i];
      max = numbers[i];
    }

    if (numbers[i] >= max) {
      max = numbers[i];
    }

    if (numbers[i] <= min) {
      min = numbers[i];
    }

    free(new);
  }

  wprintf(L"Converted array: [");

  for (int i = 0; i < n; i++) {
    wprintf(L" %ld Ohm ", numbers[i]);
  }

  wprintf(L"]\n\n");

  wprintf(L"Max element: %ld Ohm\n", max);
  wprintf(L"Min element: %ld Ohm\n", min);

  for (int i = 0; i < n; i++) {
    free(array[i]);
  }

  free(array);

  return 0;
}

当前节目输入/输出的示例:

Enter n: 3
Enter n-elements:

12 kOhm
3 kOhm
1 Ohm

// Must be 12 kOhm, 3 kOhm, 1 Om
Start array: [ 12 kOhm
   kOhm
   Ohm
 ]
// Must be 12000 Ohm, 3000 Ohm, 1 Ohm
Converted array: [ 12000 Ohm  0 Ohm  0 Ohm ]

Max element: 12000 Ohm
Min element: 0 Ohm

1 个答案:

答案 0 :(得分:0)

混合fgetswwscanf是一个坏主意。

问题在于:

  ...
  for (int i = 0; i < n; i++) {
    wchar_t temp;
    array[i] = malloc(256 * sizeof(wchar_t));
    wscanf(L"%c", &temp);
    fgetws(array[i], 2560, stdin);
  }
  ...

您正在使用wscanf(L"%c", &temp);来吸收wscanf遗留的换行符。你应该只在wscanf之后这样做一次:

  ...
  wchar_t temp;
  wscanf(L"%c", &temp);

  for (int i = 0; i < n; i++) {
    array[i] = malloc(256 * sizeof(wchar_t));
    fgetws(array[i], 2560, stdin);
  }
  ...

但最好不要先将wscanffgetsw混合在一起。

我想你使用的是Visual Studio。如果是,请学习如何使用调试器,它非常易于使用且功能非常强大。如果不是,请了解如何使用调试器。

但是在你的程序中可能还有其他与你的问题无关的问题,我没有检查。