如果它之前导致错误,fprintf会怎么做?为什么?

时间:2018-01-07 08:00:49

标签: c printf

评论此C代码的输出:

#include <stdio.h>
int main()
{
  char c;
  int i = 0;
  FILE *file;
  file = fopen("test.txt", "w+");
  fprintf(file, "%c", 'a');
  fprintf(file, "%c", -1);
  fprintf(file, "%c", 'b');
  fclose(file);
  file = fopen("test.txt", "r");
  while ((c = fgetc(file)) !=  -1)
      printf("%c", c);
  return 0;
}

a)a

b)无限循环

c)取决于fgetc返回的内容

d)取决于编译器

答案:a

说明:无。

为什么答案是?

我认为这可能来自声明的答案:“fprintf(file,”%c“, - 1)”。 发生错误后, 为什么没有程序输出b?

1 个答案:

答案 0 :(得分:1)

从技术上讲,答案是(d),取决于编译器。这是因为char可能是无符号的,在这种情况下,c = fgetc(file)永远不会评估为-1。相反,可以对char进行签名,在这种情况下c = fgetc(file)可以评估为-1。

分配的结果是分配给左侧的值(不是右侧的值,而是右侧的值转换为左侧的类型)。因此,如果char是无符号的,那么c = fgetc(file)总是具有无符号char的某个值,因此它永远不会为负且永远不会为-1。程序然后永远循环。

如果char已签名,则在正常情况下,第二个fgetc(file)评估会返回写入-1时写入文件的字符。请注意,对于%cfprintf将其int参数转换为unsigned char(即使char已签名)并写入。因此,编写-1会导致UCHAR_MAX写入文件。同样,fgetc会将unsigned char转换为int。因此,在c = fgetc(file)中,我们为签名的char分配了值UCHAR_MAX(通常为255)。对于分配,此值将转换为签名char。当转换的值不适合新类型时,存在实现定义的结果或实现定义的信号。如果实现产生-1,则程序通常在打印“a”后停止。如果实现引发信号,则通常通过终止程序来处理它。如果实现既没有信号也没有产生-1,程序将继续打印生成的字符,然后打印“b”。之后,fgetc通常会返回EOF。如果将EOF转换为char的结果为-1,则程序将停止。否则,它会发出信号或继续无限期地将EOF转换为char的结果。

(注意:问题暗示fprintffprintf(file, "%c", -1)引起的错误。在正常情况下,fprintf中没有错误。对于此调用,unsigned char会写入结果将-1转换为fopen到文件。)

此外,我们必须考虑fclose可能失败(例如,由于权限),fopen可能会失败(例如,由于可用磁盘空间或设备错误),fclose可能会失败(例如,因为另一个进程正在删除fopenpublic class CameraActivity extends AppCompatActivity { private ImageButton mProfileImage; Bitmap photo; private static final int CAMERA_REQ = 1; StorageReference mstorageRef; String userId; private FirebaseAuth mAuth; FirebaseUser firebaseUser; FirebaseDatabase firebaseDatabase; DatabaseReference ref; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mProfileImage = (ImageButton) findViewById(R.id.image_holder); firebaseDatabase = FirebaseDatabase.getInstance(); ref = firebaseDatabase.getReference("ProfileInfo"); mAuth = FirebaseAuth.getInstance(); firebaseUser = mAuth.getCurrentUser(); // userId = firebaseUser.getUid(); mProfileImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, CAMERA_REQ); } }); } public void submit(){ ByteArrayOutputStream stream = new ByteArrayOutputStream(); photo.compress(Bitmap.CompressFormat.JPEG, 100, stream); byte[] b = stream.toByteArray(); StorageReference storageReference =FirebaseStorage.getInstance().getReference().child("documentImages").child("noplateImg"); //StorageReference filePath = FirebaseStorage.getInstance().getReference().child("profile_images").child(userID); storageReference.putBytes(b).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { Uri downloadUrl = taskSnapshot.getDownloadUrl(); Toast.makeText(CameraActivity.this, "uploaded", Toast.LENGTH_SHORT).show(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Toast.makeText(CameraActivity.this,"failed",Toast.LENGTH_LONG).show(); } }); } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == CAMERA_REQ && resultCode ==RESULT_OK) { photo = (Bitmap) data.getExtras().get("data"); submit(); } } } 之间的文件。所以没有一个答案是完整的。