我正在尝试做一个脚本来读取和编辑一个文件,并且我正在用fopen来完成它。
我的问题是,当fwrite应该输入单词TEST时,它也会删除一些东西,并输入一些数字,这是没有理由的。
这是我的密码:
if (($gestor = fopen("files/prueba.pim", "c+")) !== FALSE) {
while (($datos = fgetcsv($gestor, 1000, "<br>")) !== FALSE) {
$numero = count($datos);
for ($c=0; $c < $numero; $c++) {
if ("G81"==substr($datos[$c], 0, 3)){
fwrite($gestor, "COMIENZO DE CICLO".PHP_EOL);
}else {
if (";"!=substr($datos[$c], 0, 1)) echo utf8_encode($datos[$c]."\n");
if ("X"==substr($datos[$c], 0, 1) or "Y"==substr($datos[$c], 0, 1))
fwrite($gestor, "TEST".PHP_EOL);
}
}
}
fclose($gestor);
}回声只是为了测试目的。
我无法正确地粘贴输入和输出,不知道为什么,所以我把它粘贴在巴斯托,对不起。
正如您在输出中看到的,G81 I-1. F500.之后的2行消失了,从Y开始的一些行中也出现了随机数和空白空间。
发布于 2015-05-18 11:53:31
为什么它不能像你认为的那样起作用
实际上,你认为随机数是输入文件的一部分。因为您从文件中读取,然后将其写入其中,所以需要覆盖输入文件中的行片段。
例如,输入文件中的16-19行如下:
G81 I-1. F500.
X-79.803
Y64.947
X-81.468 Y67.451代码使用(fgetcsv())读取行COMIENZO DE CICLO,然后在当前文件指针位置(即行18的开头)写入一条新行。17和18行包含15个字符和两个换行符。看起来,您正在Windows上运行代码;它使用两个字符来表示一条新行,这使这两行总共有19个字符。
碰巧,COMIENZO DE CICLO有17个字符;在它之后编写的新行增加了两个字符,总共有19个字符。这样,输入中的17和18行将被包含文本COMIENZO DE CICLO的一行完全替换。
这就是16-18在输出文件中出现的方式:
G81 I-1. F500.
COMIENZO DE CICLO
X-81.468 Y67.451下一次对fgetcsv()的调用是从当前的文件指针位置读取的,这是在行18的开头(它以前是fwrite()之前的行19;行号是为人类使用的,代码使用文件开头的偏移量来保持其内部预订)。原始行18 (Y64.947)的内容被代码忽略,然后被覆盖。没有经过处理就丢失了。
文件中的下一行(在第一个fwrite()之后的行,原始文件中的19-21行):
X-81.468 Y67.451
X-86.995 Y64.947
X-97.3 Y68.781代码读取行18 (X-81.468 Y67.451),并决定必须使用fwrite('PRUEBA'.PHP_EOL)。当前文件指针位于行19 (X-86.995 Y64.947行)的开头。fwrite('PRUEBA'.PHP_EOL)覆盖该行中的第一个6+2字符:
X-86.995 Y64.947 <--- original
^^^^^^^^
PRUEBA.. <--- replacement(我使用了点而不是新的行字符)将其更改为:
PRUEBA
Y64.947在Y64.947之前有一个空格字符。它在输入文件中,没有被覆盖。
X-86.995部分在不被读取的情况下永远丢失,下一次对fgetcsv()的调用将读取行Y64.947,并且很可能不会做您想做的事情。
这种情况一直持续到文件结束为止。
如何使它变得正确
下面的代码显示了如何正确处理该文件。您需要使用将不需要替换的输入文件中读取的部分放入输出文件的代码来完成它。插入这段代码的地方标记了一个大注释,这也建议了在那里写什么。
$gestor = fopen("files/prueba.pim", 'r');
$output = fopen('files/output.txt', 'w');
// Test if fopen() succeeded for both files
if ($gestor == FALSE || $output == FALSE) {
// Handle the error somehow (return from function or exit the program
// or display an error, it depends on your application).
exit(1);
}
// Read, process, write
while (($datos = fgetcsv($gestor, 1000, "<br>")) !== FALSE) {
$processed = FALSE;
$numero = count($datos);
for ($c = 0; $c < $numero; $c ++) {
if ("G81" == substr($datos[$c], 0, 3)) {
fwrite($output, "COMIENZO DE CICLO".PHP_EOL);
$processed = TRUE;
} else {
// if (";" != substr($datos[$c], 0, 1)) {
// echo utf8_encode($datos[$c]."\n");
// }
if ("X" == substr($datos[$c], 0, 1) or "Y" == substr($datos[$c], 0, 1)) {
fwrite($gestor, "TEST".PHP_EOL);
$processed = TRUE;
}
}
}
// Here you probably need to fwrite($output) the rows that didn't match
// the conditions above (nothing was output for them)
//
// This is how I would write it:
// if (! $processed) {
// fwrite($gestor, implode('<br>', $datos).PHP_EOL);
// } ^
// +---------------------------+
// Put here the same string you used as the third argument to fgetcsv()
}
// Close both files then rename them
fclose($gestor);
fclose($output);
// Remove the previous backup, if any
if (file_exists('files/prueba.pim.backup')) {
unlink('files/prueba.pim.backup');
}
// Backup the input file
rename('files/prueba.pim', 'files/prueba.pim.backup');
// Replace the input file with the output file
rename('output.txt', 'files/prueba.pim.backup');https://stackoverflow.com/questions/30301068
复制相似问题