【问题标题】:An assignment requires that I gather a name with 2 scanf's一项任务要求我收集一个带有 2 个 scanf 的名称
【发布时间】:2012-05-21 00:06:12
【问题描述】:

这是我的第一个 C 语言超级初学者计算机编程问题。

我需要进行设置,以便有人可以在输入中输入他们的全名。这是规格的一部分 -

“你必须想一想如何让打印的名称与所有其他列对齐。第一个提示是它涉及将字符串连接在一起,称为连接。试一试,如果您无法弄清楚,请查看此文件夹中的下一个文档;它包含其他提示。此作业的部分目的是隐含地教您连接。不要使用制表符 (\t) 并确保您的C/C++ 编辑器不生成制表符。

不要在这个程序中使用gets()。使用 scanf() 输入交互信息。如果你尝试使用gets(),你可能会非常沮丧。

实质上,报告中出现的所有数字都应右对齐和小数对齐。摘要中出现的所有数字都应不带前导空格(通常将数字与前一个单词分开的空格除外)。小时工资金额可以小于 10.00,因此请务必小心格式化。示例输出可能看起来是正确的,但如果事情与 10.00 美元以下的小时工资不相符,您仍然可能会被扣半分。” 附加提示:

  • 您可以假设员工姓名始终是两个名字,一个名字和一个姓氏,用空格分隔。还假设在名字或姓氏中从来没有任何空格。这允许您使用两个 scanf() 调用而不是一个 gets() 调用。 gets() 会引入一些奇怪的东西,使事情在以后无法正常工作。

  • 您也可以假设两个名称的长度都不超过 10 个字符。

  • 流程中的另一名员工的输入? question应该是单个字符。假设 N 或 n 将停止循环,但任何其他字符将继续循环。

有人知道怎么做吗?当我使用gets(他说不要这样做)时,循环会在第二次出现问题,它会在一行中询问姓名和薪水。如果我尝试使用 2 个 scanf 语句,我会崩溃或只有 1 个名称输入。

我认为唯一的方法是将名称输出到文本文件,然后再次读取它们。但是还有其他方法吗?我不允许单独询问姓名。正如规范中所说,用户可能会键入带有一个空格的全名。

这是我到目前为止编写的代码。我还需要所有总时间、加班时间和正常时间的总计。

//stupid program

#include <stdio.h>
#include <strings.h>
#include <math.h>

//global variables

FILE *reportfile;   //output file
char department[21];
int count;
char name[21];
float hoursworked;
float hourlywage;
float overtimehoursworked;
float overtimehourlywage;
float gross;
char again;
char firstname;
char lastname;
float tothoursworked;
float totovertimehoursworked;
float totgross;

const float overtimerate = 1.5;
const float overtimethreshold = 40; //hours needed to get overtime


//function prototypes

void GetInfo(void);
void Finalreport(void);

//main

int main(void)
{

   reportfile = fopen("c:\\class\\kpaul-pay.txt","w");  //open output file

    //////////////////////////////////////////////////
     //        initialize accumulating variables
     /////////////////////////////////////////////////


     count = 0;
     tothoursworked = 0;
     totovertimehoursworked = 0;
     totgross = 0;

   GetInfo();

   fclose(reportfile);         //close output file




return 0;

}

void GetInfo (void)
{
    printf("Mountain Pacific Corporation\n");
    printf("Department Salary Program\n\n");
    printf("Please enter the name of the department: ");
    gets(department);
    fprintf(reportfile, "Mountain Pacific Corporation\n");
    fprintf(reportfile, "Department Salary Program\n\n");
    fprintf(reportfile, "%s\n\n", department);
    fprintf(reportfile, "Employee                Reg Hrs        Overtime Hrs                      Gross\n");
    fprintf(reportfile, "-----------------------------------------------------------------\n");

    do {


   printf("\nEnter employee #1: ");
   gets(name);

   printf("Enter the hourly wage of %s", name);
   scanf("%f", &hourlywage);

   printf("\nEnter total number of hours: ");
   scanf("%f", &hoursworked);

   if (hoursworked<=overtimethreshold)
    overtimehoursworked = 0;

   else if (hoursworked > overtimethreshold)
   overtimehoursworked = hoursworked - overtimethreshold;

   gross = (hoursworked*hourlywage) + (overtimehoursworked*overtimehourlywage);

       fprintf(reportfile, "%s%16.2f(%4.2f)%12.2f(%4.2f)    $%7.2f", name, hoursworked,     hourlywage, overtimehoursworked, hourlywage * overtimerate, gross);

       tothoursworked = tothoursworked + hoursworked;
       totovertimehoursworked = totovertimehoursworked +overtimehoursworked;
       totgross = totgross + gross;


      printf("\n");
      printf("Would you like another conversion? ");
      scanf ("%s", &again);

      printf("\n\n");

   } while (again!='N' && again!='n');

}

【问题讨论】:

  • 请发布您的代码,这样会更容易讨论问题并帮助您解决代码中的问题。
  • 我放了代码。感谢您的回复。
  • "...当我使用gets(他说不要这样做)..." 那你为什么要这样做? :)
  • 因为我不知道用scanf怎么做,这是必需的。您如何遵循他的规范并允许某人使用 2 个 scanfs 输入带有空格的名称?
  • 您可能需要两个字符数组,一个用于名字,一个用于姓氏。您应该在对scanf() 的一次或两次调用中使用两个scanf() 转换规范。当然,您将检查对每个读取函数的每次调用的结果(scanf()gets() 如果您使用它等等;fopen() 也可能失败!)。如果数组长度为 20 个字符,您将通过指定 "%19s" 来确保 scanf() 不会出现缓冲区溢出。而你的scanf() 'Again' 不会读取单个字符(%c),而是读取一个保证溢出的字符串(%s)。

标签: c scanf strcat do-loops


【解决方案1】:

需要谨慎使用scanf 格式字符串。 %s 表示一个由空格分隔的字符串,用非技术术语来说,scanf 将读取字符,直到找到一个空格字符,例如制表符或空格。

这会造成读取多个单词的问题,这可以通过在格式字符串中使用多个%s来解决,您必须在格式字符串之后为每个单词提供一个单独的数组作为参数,例如

scanf("%s%s%s", string1, string2, string3)

这个scanf 调用需要来自用户的三个单词,其中每个单词由一个空格分隔。确保为每个数组分配了内存,否则您将写入程序通常不拥有的内存,从而导致程序崩溃。通过在格式字符串中多次使用scanf 和单个%s 可以达到与上述代码完全相同的效果。

如果您需要将所有内容都作为一个字符串和同一个数组,您可以使用strcat,它将两个字符串连接在一起。该函数使用简单,但再次确保在调用strcat 之前为您的参数分配数组,否则可能会导致崩溃或意外行为。

以下是对这两个函数的引用:

scanf - http://www.cplusplus.com/reference/clibrary/cstdio/scanf/

strcat - http://www.cplusplus.com/reference/clibrary/cstring/strcat/

希望这会有所帮助 =]

【讨论】:

  • 谢谢。它可能。我不确定如何为此编写代码。虽然我认为你在正确的轨道上,因为我应该使用 strcat 和 2 scanf's。我再试试scanf("%s%s%s", string1, string2, string3),但上次我觉得它崩溃了,我也不知道如何设置strcat代码。
  • 这样的东西应该可以工作:scanf("%s%s", firstname, surname);strcat(name, firstname);strcat(name, " ");strcat(name, surname);这会将输入的全名放入name,中间有一个空格。我在您的代码示例上进行了尝试并修复了您提到的问题,但出现了一些其他错误,我会让您找出 =P
  • 非常感谢。终于又开始工作了,到目前为止一切顺利。
【解决方案2】:

scanf 格式为 %s 将接受以空格分隔的字符串。

崩溃很可能是由于输入字符串溢出(或未能为输入字符串保留空间)引起的。

【讨论】:

  • 也许我的代码会有所帮助。现在它得到了,但我怎样才能将它更改为 2 scanf,正如它在规范中所说的那样?
猜你喜欢
  • 1970-01-01
  • 2012-04-11
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-13
  • 2022-01-11
  • 2017-08-15
相关资源
最近更新 更多