C控制台输入

时间:2016-01-25 22:22:12

标签: c string input

我似乎无法谷歌这一点,因为一切都变成C ++或C#(旁注:任何简单的搜索C特定的方法?)。所有我想弄清楚的是如何接受一个控制台字符串输入,以便我知道它的长度,所以我可以通过使用for循环向后索引它以相反的顺序返回它。我过去有过一点C ++经验,但从未真正使用过控制台IO。任何帮助表示感谢,谢谢。

5 个答案:

答案 0 :(得分:2)

  1. 使用fgets()阅读。
  2. 处理可能的尾随\n
  3. 查找长度
  4. 反向打印。

    char buf[100];
    if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOF();
    buf[strcspn(buf, "\n")] = '\0';  // lop off potential trailing \n
    size_t len = strlen(buf);
    while (len) {
      putc(buf[--len], stdout);
    }
    

答案 1 :(得分:1)

您可以使用fgets功能从标准输入中读取。

char buf[80];

if (fgets(buf, 80, stdin) != NULL)
    /* buf now contains the first 80 chars of the input */

注意: NOT 使用gets因为它很危险 - 它可能会溢出输入缓冲区。

答案 2 :(得分:1)

您需要留出一些空间来存储输入;因为你事先并不知道输入的大小,所以你必须对存储有一点创意。

一种常见的策略是使用一个小的固定大小的缓冲区来读取输入流,并使用一个动态的,可调整大小的缓冲区来存储整个字符串,如果它的结束时间比固定大小的缓冲区可以处理的长。这样,您可以在离散块中读取任意长的输入行,然后将块粘贴在一起,根据需要调整目标缓冲区的大小。

您将在循环中从控制台读取固定大小的块并将其存储到动态缓冲区,直到您看到换行符,此时退出输入循环。理想情况下,固定大小的缓冲区应足够大,以处理大多数合理的情况,这样您就不需要扩展动态缓冲区。

过分冗长(未经测试!)示例:

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

#define INPUT_BUF_SIZE 21 // handle strings up to 20 characters in length

int main( void )
{
  /**
   * Set aside a fixed-size buffer to store input from the console.  This
   * buffer cannot be resized after it has been allocated.
   */
  char inputBuf[INPUT_BUF_SIZE]; 

  /**
   * Dynamically allocate a buffer to store the final string; 
   * its initial size is the same as the fixed buffer.  If necessary,
   * this buffer may be extended with the realloc function.  We're using
   * calloc instead of malloc to make sure the initial array contents
   * are set to 0.
   */
  char *finalBuf = calloc( INPUT_BUF_SIZE, sizeof *finalBuf ); 

  /**
   * finalBufSize tracks the total size of the dynamic buffer; finalBufLen
   * tracks the length of the string currently stored in the buffer.
   * These are not the same thing.  
   */
  size_t finalBufSize = INPUT_BUF_SIZE;
  size_t finalBufLen = 0; // initially no string stored in the buffer

  /**
   * Read from standard input into the fixed-size buffer; loop until
   * we see EOF or there's an error on input.
   */
  while ( fgets( inputBuf, sizeof inputBuf, stdin ) )
  {
    /**
     * If there isn't enough space left in finalBuf to store
     * the latest chunk, double the size of finalBuf.  This strategy
     * minimizes the number of times you have to call realloc (which
     * can be expensive).  
     */
    if ( strlen( inputBuf ) + finalBufLen > finalBufSize )
    {
      /**
       * *Always* assign the result of realloc to a temp variable; if the
       * call fails it will return NULL, and if you overwrite the value
       * of finalBuf with NULL, you'll lose your only reference to any
       * previously allocated memory.  
       */
      char *tmp = realloc( finalBuf, finalBufSize * 2 );
      if ( tmp )
      {
        finalBuf = tmp;
        finalBufSize *= 2;
      }
      else
      {
        /**
         * We can't extend the buffer anymore, so we'll exit the
         * loop and work with what we have.
         */
        fprintf( stderr, "Could not extend storage buffer, exiting input loop\n" );
        break;
      }
    }

    /** 
     * Append the input string to the target buffer.
     */
    strcat( finalBuf, inputBuf );
    finalBufLen = strlen( finalBuf );

    /**
     * Did we see a newline in the last input chunk?  If so,
     * remove that newline from the final string (unless you
     * want to include that in your reversal) and exit
     * the loop.
     */
    char *newline = strchr( finalString, '\n' );
    if ( newline )
    {
      *newline = 0; // overwrite the newline character with the string terminator
      break;
    }
  }

此时,finalBuf包含来自控制台的输入,您可以将此字符串反转以进行输出。完成后,释放已使用free功能分配的内存,如下所示:

free( finalBuf );

理想情况下,您将所有输入处理分离到其自己的功能中,但这是一个很好的说明。

答案 3 :(得分:0)

我编写了这个函数,将stdin的输入放入缓冲区,用于uni中的cli项目。

它通过char读取stdin char,它没有缓冲区溢出。

/*max line lenght*/
#define CLI_MAX_CMD_LEN 1024

/*get_line copies characters from stdin to buffer pointed by buf, stopping when a
  carriage return or newline is encountered. It returns -1 on errors, otherwise strlen count */
int get_line(char *buf) {
    int i,c;
    for (i=0;i<CLI_MAX_CMD_LEN;i++) {
        c = getchar();
        switch (c) {
            /*if terminating char is found an error has occurred*/
            case '\0':
                printf("found '\\0' instead of '\\n'\n");
                return -1;
            case '\t':
                /*show possible commands*/
                autocomplete(buf);
                break;
            case EOF:
                /* prints the warning to stdout */
                printf("End of file reached\n");
                /* continue to execute following cases code */ 
            case '\n':
            case '\r':
                buf[i] = '\0';
                return i;
            default :
                buf[i] = c;
        }
    }

    /*if end of buffer is reached put terminating char on last element
      means that an error has occurred*/
    buf[CLI_MAX_CMD_LEN] = '\0';
    return -1;
}

答案 4 :(得分:0)

这是我的解决方案,但有递归:

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

#define N 20

void reverseW(char *, int);

int main()
{
char tmp[N], *string;

printf("Type a String:\n");
scanf("%s", tmp);

string=(char*)malloc((strlen(tmp)+1)*sizeof(char));
if (string==NULL)
{
    printf("Error !\n");
    exit(0);
}
strcpy(string, tmp);

reverseW(string, strlen(string));
printf("\nThe reverse of %s is %s !\n", tmp, string);

free(string);
return 0;
}

void reverseW(char *word, int size)
{
char tmp;
if (size>1)
{
    tmp=word[0];
    word[0]=word[size-1];
    word[size-1]=tmp;
    reverseW(word+1, size-2);
}
return;
}