如何获取输入以提示用户输入两个字符并使用它们进行交换?

时间:2014-03-04 20:57:26

标签: c sorting loops pointers

我在Ubuntu中使用GCC在ANSI C中创建一个小应用程序。应用程序应该通过在数组中交换两个字母来解密消息。

我的主要课程:

#include "CipherCode.h"

char cipherText[] = "PUCXHTULUL, XW AELW, JUAJ TXJ FOCTXWU EH XW OCCQLPOWCU RXAT ATU DUZ GXJA. RTUW ATU FUJJOBU XJ LUCUXIUP, TU JUAJ ATU DUZ RTUUGJ AQ ATU";

int main(void) {
    char ch = 0;
    char chLetter, chReplacement;

    char *pLetter = chLetter;
    char *pReplacement = chReplacement;

    int cipherStats[ALPHABET_SIZE] = { 0 };
    char chAlphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    int *pCipherStats = cipherStats; 
    char *pCipherText = cipherText;
    char *pAlphabet = chAlphabet;

    do {
        DisplayCipherText(pCipherText);
        GetFrequency(pCipherText, pCipherStats);
        DisplayCipherStats(pCipherStats, pAlphabet, 26);
        chLetter = GetLetter("Enter character to substitute:");
        chReplacement = GetLetter("Swap this with character:");
        Decipher(pCipherText, pReplacement);
        printf("%s", "\nPress 'n' to exit or any other key to continue...\n"); /* prompt to continue looping */
    } while ((ch = getchar()) != 'n'); /* loop unless user enters char 'n' */

    return EXIT_SUCCESS;
}

我的CipherCode.c文件:

#include "CipherCode.h"

char GetLetter(const char* prompt) {
    char ch = '\0';
    do {
        printf( "%s", prompt ); 
        fflush(stdout);
        ch = toupper(getchar());
        printf( "%c\n", ch );
    } while (!isalpha(ch));
    return ch;
}

int GetFrequency(const char *pCipherText, int *pCipherStats) {
    printf("Frequency analysis:\n");
    for (; *pCipherText != '\0'; pCipherText++) {
        if (isalpha(*pCipherText)) {
            int index = toupper(*pCipherText) - 'A';
            if ( index >= 0 && index < 26 ) {
                pCipherStats[index]++;
            }
            else {
                fprintf(stderr, "%c gives invalid index: %d\n", *pCipherText, index);
            }
        }
    }
    return EXIT_SUCCESS;
}

void DisplayCipherText(char *pCipherText) {
    for (; *pCipherText != '\0'; pCipherText++) {
        printf("%c", *pCipherText);
    }
    printf("\n\n");
}

void DisplayCipherStats(int *pCipherStats, char *pAlphabet, int size) {
    int i;
    for (i = 0; i < size; i++) { /*for each letter in the alphabet*/
        printf("%1c:%-4d", *pAlphabet++, *pCipherStats++); /*print frequency information*/
    }
    printf("\n\n");
}

void Decipher(char *pCipherText, char *pReplacement) {
    for (; *pCipherText != '\0'; pCipherText++) {
        if (*pCipherText == *pReplacement) {
            SortChar(pCipherText, pReplacement);
        }
    }
}

void BubbleSort(int *pInt, char *pCh) {
    int i, j;
    for (i = ALPHABET_SIZE-1; i >= 0; i--) {
        for (j = 0; j < i; j++) {
            if (*(pInt+j) < *(pInt+j+1)) {
                SortChar(pCh+j, pCh+j+1);
                SortInt(pInt+j, pInt+j+1);
            }
        }
    }
}

void SortInt(int *pIntA, int *pIntB) {
    int tempInt; /*temp variable*/
    tempInt = *pIntA; /*store old value before it is overwritten*/
    *pIntA = *pIntB; /*overwrite old value*/
    *pIntB = tempInt; /*complete the swap*/
}

void SortChar(char *pChA, char *pChB) {
    char tempCh; /*temp variable*/
    tempCh = *pChA; /*store old value before it is overwritten*/
    *pChA = *pChB; /*overwrite old value*/
    *pChB = tempCh; /*complete the swap*/
}

我的标题文件:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define ALPHABET_SIZE 26

/*
* global variables
*/
extern char cipherText[];

/*
* function prototypes
*/
char GetLetter(const char*);
int GetFrequency(const char*, int*);
void DisplayCipherText(char*);
void DisplayCipherStats(int*, char*, int);
void Decipher(char*, char*);
void BubbleSort(int*, char*);
void SortInt(int*, int*);
void SortChar(char*, char*);

我希望程序采用chLetter并用chReplacement替换cipherText中出现的所有chLetter。对于do循环的每次迭代,我想显示cipherText,然后分析cipherText中字母的频率,然后显示频率,然后请求chLetter,然后请求chReplacement,最后用chReplacement交换chLetter。

程序必须使用指针来引用数组的内容。我还必须使用我的排序功能来破译文本。

非常感谢任何帮助。感谢。

2 个答案:

答案 0 :(得分:1)

char GetLetter(char chLetter) {
    char *pLetter = scanf("Enter character to substitute: %c", &chLetter);
    return *pLetter;
}

^指定scanf格式字符串的错误方式,格式字符串用于 匹配来自缓冲区的输入而不是用于显示提示。 scanf返回数字 它从缓冲区找到的参数不是char *

而是做这样的事情:

char GetLetter() 
{
  printf( "%s", "Enter character to substitute:"); 
  fflush(stdout);
  return getchar();
}

或为了使其更灵活,请在参数中指定提示符:

char GetLetter(const char* prompt) 
{
  printf( "%s", prompt ); 
  fflush(stdout);
  return getchar();
}

然后你可以用

来调用它
char chReplace = GetLetter("Enter character to substitute:");
char chWith = GetLetter("Swap this with character:");

使用此功能

int GetFrequency(char *pCipherText, int *pCipherStats) {
printf("Frequency analysis:\n");
for (; *pCipherText != '\0'; pCipherText++) { /*check if at the end of the array*/
    char ch = *pCipherText; /*store current letter as a char*/
    if (isalpha(ch)) pCipherStats[ch - 'A']++; /*if character is a letter, store ascii value in array and increment array*/
}

^你似乎假设所有输入字母都是大写字母,也许你应该通过首先将字符转换为大写来确保它。在编程时总是很好,更安全而不是遗憾。通常,通过将参数用作临时变量来修改参数是不好的方式,当函数更复杂时,它会使代码混乱。而是使用本地var例如

int GetFrequency(const char *pCipherText, int *pCipherStats) 
{
  char* p = pCiperText;
  printf("Frequency analysis:\n");
  for (; *p != '\0'; ++p) 
  {
    if (isalpha(*p)) 
    {
      int index = toupper(*p) - 'A';
      if ( index >= 0 && index < 26 )
      {
        pCipherStats[index]++;
      }
      else
      {
        fprintf(stderr, "%c gives invalid index: %d\n", *p, index );
      }
    }
  }
  ...

说,你可以使GetLetter功能更加强大:

char GetLetter(const char* prompt) 
{
  char ch = '\0';
  do
  {
    printf( "%s", prompt ); 
    fflush(stdout);
    ch = toupper(getchar());
    printf( "%c\n", ch );
  }
  while ( !isalpha(ch) );
  return ch;
}

答案 1 :(得分:0)

GetLetter()GetReplacement()有多个问题。

第一行将其定义为采用char并返回char的函数。 这实际上没问题,但是因为你没有使用传递的值 chLetter,您根本不需要传递它。

char GetLetter(char chLetter) {

此行执行您认为的操作。它将使用该文本 "Enter the character ..."作为提示,但尝试匹配输入。这个 意味着scanf不会失败的唯一方法是用户键入 整个字符串,这显然不是你想要的。 scanf返回char *,但是int,表示有多少 输入项已成功匹配,或EOF以防输入结束 在匹配第一个项目之前达到或发生错误。分配int 指针的值通常没有意义

char *pLetter = scanf("Enter character to substitute: %c", &chLetter);

在这里,您尝试取消引用未指向有效的指针 记忆位置。

return *pLetter;
}

一个简单的实现可能是:

/** Prompt for inputting a single character
 *
 * Reads the first character and then discards the rest of the line.
 * The `text` parameter is the prompt string.
 * Returns an int so we can indicate EOF, which isn't representable by char
 */
int prompt_char(const char *text) {
    int c, tmp;
    printf("%s: ", text);
    c = getchar();
    do {
        tmp = getchar();
    } while (tmp != '\n' && tmp != EOF);
    return c;
}

您可以在main()中使用这样的内容:

do {
    ...
    chLetter = prompt_char("Enter character to substitute");
    chReplacement = prompt_char("Swap this with character");
            if (chLetter == EOF || chReplacement == EOF) {
                // do something, e.g. break from the loop or exit the program
            }
    ...
} while (...)