簡體   English   中英

C-從字符串中分離數字

[英]C - separating number from the string

我編寫了一個簡單的程序,該程序在空格后返回值:例如,輸入“ alababa 4”給出了返回值4,在沒有空格的情況下,它的值為0。但是現在我想掃描該字符串,但是它不起作用,我不知道我在哪里犯錯。

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


int main(){

//char * string="alababa 4" - it worked that way
char * string;

scanf("%c", &string);
int dlugosc=strlen(string);

  for(int i=0;i<=dlugosc-1; i++)
  {

  char temp;
  temp=string[i];
  char str2[] = " ";
  if(temp==' ')
  {

      char * pZnak = strpbrk( string, str2 );
      printf( "%s \n", pZnak ); 
      return pZnak[1]-48;  

  }

  }
  return 0;
}

第二個問題,為什么收益比應有的收益大48?

您創建了一個指向char的指針,但沒有為其分配內存。 最簡單的方法是創建一個具有固定大小的char數組。 scanf %c表示讀取單個字符,使用%s讀取字符串,但是scanf()僅讀取空格符號,而不讀取'\\ n'。 當您鍵入“ alababa 4”時,它將僅讀取alababa。 您可以使用gets()fgets()讀取整個字符串。 另外,變量string已經是您不需要在&那里使用的指針。 正確的語法為: scanf("%s", string); 但正如我所說,它只會讀第一個單詞。 程序中的pZnak[0]保留'space',而pZnak[1]保留'4'。 “ 4”的ASCII碼為52。這是從鍵盤讀取字符串並在屏幕上的空格符號后打印所有內容的程序。

#include <stdio.h>  // for printf() and gets()
#include <string.h> // for strpbrk()

int main(void) {
    char string[80]; // It can contain a string of 79 symbols + '/0'
    char *checkStr = " ";
    gets(string);
    char *ptr = strpbrk(string, checkStr);
    printf("%s\n", ptr);
    return 0;
}

這里的問題是完全不同的。 首先,您傳遞了一個指針變量的地址,該變量未指向scanf可以存儲輸入數據的某個有效內存位置。 您已在代碼中調用了未定義的行為。

您可以使用sscanf來完成所需的操作,該方法基本上在緩沖區上使用scanf sscanf(buf,"%s%d",str,&num) 但是在這種情況下,如果失敗,將不會返回值2 但是這種解決方案並不是很好scanf類適合格式化輸入(很多麻煩都與scanf一起進行錯誤檢查)。 更好的方法是使用strtok解析輸入字符串。 如果您有一個通則就完成了。 沒有提供數字或數字。 如果返回2個令牌,則使用strtol獲取第二個令牌的整數值。

如果您知道只有1位數字,則可以執行簡單的循環-並檢查您在上一段中找到的第二個標記。 如果您得到一個數字並且它是唯一的數字,則可以確保這是您必須解析的唯一數字。 您可以簡單地將其存儲在int變量中。

插圖代碼:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#define MAXLEN 100
int main(){
    char s[MAXLEN+1];
    int numParsed = 0;
    int iter = 1;
    if(fgets(s,MAXLEN+1,stdin)!=NULL){
        char * str= strtok(s," ");

        while(str!=NULL){
            str = strtok(NULL," ");
            if(iter && str!=NULL){
                iter = 0;

                char *t;
                errno = 0;
                long n = strtol(str, &t, 10);
                if ((errno == ERANGE && (n == LONG_MAX || n == LONG_MIN))|| (errno != 0 && n == 0)) {
                    perror("strtol");
                    exit(EXIT_FAILURE);
                }
                if (t == str) {
                    fprintf(stderr, "No digits were found\n");
                    exit(EXIT_FAILURE);
                }
                if ( n >= INT_MIN && n <= INT_MAX)
                {
                    numParsed = n;
                }
                else{
                   fprintf(stderr, "Too big/small a number\n");
                   exit(EXIT_FAILURE); 
                }
            }else if(iter == 0 && str){
                fprintf(stderr, "%s\n","Input=> String[SPACE]Num" );
                exit(EXIT_FAILURE);
            }

        }
        if(iter == 0)
            printf("[%d]\n",numParsed );
        else
            printf("%s\n", "Format: String[SPACE]int");
    }
  return 0;
}

scanf("%c",...)讀取單個字符,而不是0限定的字符序列。 因此, char * string;scanf("%c", &string); 錯誤有兩個方面:(1)將字符讀入指向字符指針的指針中;(2)讀入的字符串不是預期的,而是單個字符。 並且,如果您編寫char*string;scanf("%s",string) ,則會將字符串讀入無效內存(因為指針string未指向有效分配的內存),這是未定義的行為。

您必須編寫char string[20]; scanf("%19s",string) char string[20]; scanf("%19s",string)
然后,您可以根據需要解析輸入字符串。 順便說一句:您的解析器似乎有點復雜; 一個簡單的if (scanf("%*s%d",&num)==1) { ...可以完成工作; *表示應解析%s的輸入但不將其存儲在某處,並且%d跳過之間的所有空格后,將讀取數字部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM