从一本通 "1407:笨小猴"的两个测试点未通过来谈谈Windows/Linux/macOS的换行符

原创
03/08 21:53
阅读数 164

问题:一本通1407:笨小猴(洛谷P1125 笨小猴) 第8个和第10个测试点不能通过,而相同的代码在洛谷上没问题。

#include <bits/stdc++.h>
using namespace std;


int main() {
   char ch[110];
   gets(ch);
   printf("%d.", strlen(ch));
   int n = strlen(ch), max = 0, min = 100;
   for (int i = 0; i < n; i++) {
      int t = 0;
      //if( 0x0d == ch[i]) continue; // \r(RETURN)
      for (int j = 0; j < n; j++)
         if (ch[i] == ch[j]) t++;

      if (t > max) max = t;
      if (t < min) min = t;
   }
   int x = max - min;
   if (x >= 2) {
      int flag = 0;
      for (int i = 2; i <= sqrt(x); i++) {
         if (x % i == 0) {
            flag = 1;
            break;
         }
      }
      if (flag == 0)  cout << "Lucky Word" << endl << x;
      else            cout << "No Answer"  << endl << '0';
   } else             cout << "No Answer"  << endl << 0;
   
   return 0;
}

以上代码将gets换为scanf后全过
 

#include <bits/stdc++.h>
using namespace std;
// lg: P1125 笨小猴
inline bool is_small_alpha(char x) { return 'a' <= x && 'z' >= x; }

int main() {
   char ch[110];
   //gets(ch);
   scanf("%s", ch);
   int n = strlen(ch), max = 0, min = 100;
   for (int i = 0; i < n; i++) {
      int t = 0;
      //if( 0x0d == ch[i]) continue; // \r(RETURN)
      for (int j = 0; j < n; j++)
         if (ch[i] == ch[j]) t++;

      if (t > max) max = t;
      if (t < min) min = t;
   }
   int x = max - min;
   if (x >= 2) {
      int flag = 0;
      for (int i = 2; i <= sqrt(x); i++) {
         if (x % i == 0) {
            flag = 1;
            break;
         }
      }
      if (flag == 0)  cout << "Lucky Word" << endl << x;
      else            cout << "No Answer"  << endl << '0';
   } else             cout << "No Answer"  << endl << 0;
   
   return 0;
}

增加过滤回车后一本通也AC了。

增加的一行: if( 0x0d == ch[i]) continue; // \r(RETURN)

#include <bits/stdc++.h>
using namespace std;


int main() {
   char ch[110];
   gets(ch);
   printf("%d.", strlen(ch));
   int n = strlen(ch), max = 0, min = 100;
   for (int i = 0; i < n; i++) {
      int t = 0;
      if( 0x0d == ch[i]) continue; // \r(RETURN) 
      for (int j = 0; j < n; j++)
         if (ch[i] == ch[j]) t++;

      if (t > max) max = t;
      if (t < min) min = t;
   }
   int x = max - min;
   if (x >= 2) {
      int flag = 0;
      for (int i = 2; i <= sqrt(x); i++) {
         if (x % i == 0) {
            flag = 1;
            break;
         }
      }
      if (flag == 0)  cout << "Lucky Word" << endl << x;
      else            cout << "No Answer"  << endl << '0';
   } else             cout << "No Answer"  << endl << 0;
   
   return 0;
}

 

一本通未通过的原因分析:

只过滤掉回车就OK了。由此推断一本通的测试数据在Windows系统里面生成或保存过,就多了一个回车符。

gets是以行结束或文文件结尾作为结束的。在不同的系统中行结束不同

而并不是以“混用”的原因造成:

或者将gets 改为cin,还要作点相应改动,也可以 AC。
cin, cout 是C++一族的,
gets, scanf, printf是C一族的。
这两族不要混用。

 

Windows/Linux/macOS系统中的换行符

 

换行符‘\n’和回车符‘\r’

 

(1)换行符就是另起一行  --- '\n' 10 换行(newline)

(2)回车符就是回到一行的开头 --- '\r' 13 回车(return)

所以我们平时编写文件的回车符应该确切来说叫做回车换行符 

 

二、应用:

(1)在微软的MS-DOS和Windows中,使用“回车CR('\r')”和“换行LF('\n')”两个字符作为换行符;

(2)Windows系统里面,每行结尾是 回车+换行(CR+LF),即“\r\n”;

(3)Unix系统里,每行结尾只有 换行CR,即“\n”;

(4)Mac系统里,每行结尾是 回车CR 即'\r'。

关于Mac换行

引用自:https://blog.csdn.net/menc15/article/details/71731825?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

根据Wikipedia-NewlineWikipedia-macOS

在2001年以前的Mac操作系统,称为Classic Mac OS,行末采用”\r”,这一系列操作系统的最后一个版本是1999年发布的Mac OS 9;

从2001年3月发布的Mac OS 10.0开始,行末采用”\n”,称为macOS或OS X。行末采用的就是与Unix一样的”\n”

Windows下的换行符是0x0D 0x0A,如下所示:

Linux下的换行符是0x0A,如下所示:

macOS 10.13.6中的换行符是0x0A,如下所示:

引用

  1. Linux/Windows/Mac OS中的回车与换行
转载 CharlotteMen 最后发布于2017-05-12 15:16:35 阅读数 4378 收藏

https://blog.csdn.net/menc15/article/details/71731825?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

 

本问题今天花了5、6小时。

展开阅读全文
打赏
0
1 收藏
分享
加载中
SamXIAO博主
gets, gets_s

C

文件输入/输出

定义于头文件 <stdio.h>
    
char *gets( char *str );
    (C11 中移除)
char *gets_s( char *str, rsize_t n );
    (C11 起)
(可选)
    
1) 从 stdin 读入 str 所指向的字符数组,直到发现换行符或出现文件尾。在读入数组的最后一个字符后立即写入空字符。换行符被舍弃,但不会存储于缓冲区中。
2) 从 stdin 读取字符直到发现换行符或出现文件尾。至多写入 n-1 个字符到 str 所指向的数组,并始终写入空终止字符(除非 str 是空指针)。若发现换行符,则忽略它并且不将它计入写入缓冲区的字符数。

在运行时检测下列错误,并调用当前安装的制约处理函数:

n 为零
n 大于 RSIZE_MAX
str 是空指针
在存储 n-1 个字符到缓冲区后没有遇到换行符或文件尾。

任何情况下,gets_s 首先结束读取并忽略来自 stdin 的字符,直到换行符、文件尾条件,或在调用制约处理前的读取错误。
同所有边界检查函数, gets_s 仅若实现定义了 __STDC_LIB_EXT1__ ,且用户在包含 <stdio.h> 前定义 __STDC_WANT_LIB_EXT1__ 为整数常量 1 才保证可用。
03/08 22:06
回复
举报
更多评论
打赏
1 评论
1 收藏
0
分享
返回顶部
顶部