0

Task: Converts Ohm's from 1 kOhm to 1000 Ohm etc. and find max and min values.

Example:

1 kOhm

2 Ohm

And after convert to

1000 Ohm

2 Ohm

But after input get only

1 kOhm

Ohm

Input must be with spaces. Program drops 1 char from every new line after first. I try using wscanf and other thinks but it isn't workig for me.

P.S. I must use 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;
}

Example of current program input/output:

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
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115

1 Answers1

0

Mixing fgetsw and wscanf is a bad idea.

The problem is here:

  ...
  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);
  }
  ...

You are using wscanf(L"%c", &temp); to absorb the line feed that is left over from wscanf. You should do this only once after the wscanflike this:

  ...
  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);
  }
  ...

But the best would be not to mix wscanf and fgetsw in first place.

I suppose you use Visual Studio. If yes, learn how to use the debugger, it's very easy to use and very powerful. If no, learn how to use your debugger anyway.

But further in your program there may be other problems unrelated to your question, I didn't check.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115